From 2bbf8ca9d2af3ea959a21c3729b4894bc31f088b Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 13:58:29 -0400 Subject: reorganized call Conflicts: doc/TODO lib/arel/relations/relation.rb lib/arel/relations/writes/delete.rb lib/arel/relations/writes/insert.rb lib/arel/relations/writes/update.rb lib/arel/session.rb spec/arel/unit/relations/delete_spec.rb spec/arel/unit/relations/insert_spec.rb spec/arel/unit/relations/relation_spec.rb spec/arel/unit/relations/update_spec.rb spec/arel/unit/session/session_spec.rb --- lib/arel/engine.rb | 24 ++++++++++++++++++++++++ lib/arel/relations.rb | 4 +--- lib/arel/relations/array.rb | 19 +++++++++++++++++++ lib/arel/relations/relation.rb | 9 ++------- lib/arel/relations/writes/delete.rb | 4 ++-- lib/arel/relations/writes/insert.rb | 4 ++-- lib/arel/relations/writes/update.rb | 4 ++-- lib/arel/session.rb | 8 ++++---- 8 files changed, 56 insertions(+), 20 deletions(-) create mode 100644 lib/arel/relations/array.rb (limited to 'lib') diff --git a/lib/arel/engine.rb b/lib/arel/engine.rb index 5a5ef06878..2bb4bbbd90 100644 --- a/lib/arel/engine.rb +++ b/lib/arel/engine.rb @@ -14,5 +14,29 @@ module Arel def method_missing(method, *args, &block) @ar.connection.send(method, *args, &block) end + + module CRUD + def create(relation) + connection.insert(relation.to_sql) + end + + def read(relation) + results = connection.execute(relation.to_sql) + rows = [] + results.each do |row| + rows << attributes.zip(row).to_hash + end + rows + end + + def update(relation) + connection.update(relation.to_sql) + end + + def delete(relation) + connection.delete(relation.to_sql) + end + end + include CRUD end end diff --git a/lib/arel/relations.rb b/lib/arel/relations.rb index 3394fac7cb..fd758ed15d 100644 --- a/lib/arel/relations.rb +++ b/lib/arel/relations.rb @@ -1,8 +1,6 @@ require 'arel/relations/relation' - require 'arel/relations/utilities' - require 'arel/relations/table' - +require 'arel/relations/array' require 'arel/relations/writes' require 'arel/relations/operations' \ No newline at end of file diff --git a/lib/arel/relations/array.rb b/lib/arel/relations/array.rb new file mode 100644 index 0000000000..dac65abbc2 --- /dev/null +++ b/lib/arel/relations/array.rb @@ -0,0 +1,19 @@ +module Arel + class Array < Relation + include Recursion::BaseCase + + def initialize(array, attribute_names) + @array, @attribute_names = array, attribute_names + end + + def attributes + @attributes ||= @attribute_names.collect do |name| + Attribute.new(self, name.to_sym) + end + end + + def call(connection = nil) + @array.collect { |row| attributes.zip(row).to_hash } + end + end +end \ No newline at end of file diff --git a/lib/arel/relations/relation.rb b/lib/arel/relations/relation.rb index 5d2c336a15..ef295dfdd7 100644 --- a/lib/arel/relations/relation.rb +++ b/lib/arel/relations/relation.rb @@ -32,13 +32,8 @@ module Arel "IN" end - def call(connection = engine) - results = connection.execute(to_sql) - rows = [] - results.each do |row| - rows << attributes.zip(row).to_hash - end - rows + def call + engine.read(self) end def bind(relation) diff --git a/lib/arel/relations/writes/delete.rb b/lib/arel/relations/writes/delete.rb index b1ff3bef27..0a04454e7f 100644 --- a/lib/arel/relations/writes/delete.rb +++ b/lib/arel/relations/writes/delete.rb @@ -12,8 +12,8 @@ module Arel ].compact.join("\n") end - def call(connection = engine) - connection.delete(to_sql) + def call + engine.delete(self) end end end diff --git a/lib/arel/relations/writes/insert.rb b/lib/arel/relations/writes/insert.rb index d579ad06d0..d05bd9cdc8 100644 --- a/lib/arel/relations/writes/insert.rb +++ b/lib/arel/relations/writes/insert.rb @@ -16,8 +16,8 @@ module Arel ].join("\n") end - def call(connection = engine) - connection.insert(to_sql) + def call + engine.create(self) end end end diff --git a/lib/arel/relations/writes/update.rb b/lib/arel/relations/writes/update.rb index 2e90de3a52..fd0aadb479 100644 --- a/lib/arel/relations/writes/update.rb +++ b/lib/arel/relations/writes/update.rb @@ -18,8 +18,8 @@ module Arel ].join("\n") end - def call(connection = engine) - connection.update(to_sql) + def call + engine.update(self) end end end diff --git a/lib/arel/session.rb b/lib/arel/session.rb index d9a6e4b5e4..9c2ddc535b 100644 --- a/lib/arel/session.rb +++ b/lib/arel/session.rb @@ -25,21 +25,21 @@ module Arel module CRUD def create(insert) - insert.call(insert.engine) + insert.call end def read(select) (@read ||= Hash.new do |hash, select| - hash[select] = select.call(select.engine) + hash[select] = select.call end)[select] end def update(update) - update.call(update.engine) + update.call end def delete(delete) - delete.call(delete.engine) + delete.call end end include CRUD -- cgit v1.2.3 From bdca9ed42ffea10aa6989ea3ecebedb424fa01ed Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 14:20:29 -0400 Subject: moved sql related code to its own engine area Conflicts: lib/arel/engine.rb lib/arel/extensions/object.rb lib/arel/predicates.rb lib/arel/primitives/attribute.rb lib/arel/primitives/expression.rb lib/arel/primitives/value.rb lib/arel/relations/operations/join.rb lib/arel/relations/relation.rb lib/arel/relations/utilities/externalization.rb lib/arel/relations/utilities/nil.rb lib/arel/relations/writes/delete.rb lib/arel/relations/writes/insert.rb lib/arel/relations/writes/update.rb spec/arel/unit/relations/skip_spec.rb spec/arel/unit/relations/take_spec.rb spec/spec_helper.rb --- lib/arel.rb | 3 +- lib/arel/engine.rb | 42 ------- lib/arel/engines.rb | 2 + lib/arel/engines/array/array.rb | 1 + lib/arel/engines/array/relations/array.rb | 19 ++++ lib/arel/engines/sql/christener.rb | 13 +++ lib/arel/engines/sql/engine.rb | 41 +++++++ lib/arel/engines/sql/extensions.rb | 4 + lib/arel/engines/sql/extensions/array.rb | 9 ++ lib/arel/engines/sql/extensions/nil_class.rb | 5 + lib/arel/engines/sql/extensions/object.rb | 9 ++ lib/arel/engines/sql/extensions/range.rb | 9 ++ lib/arel/engines/sql/formatters.rb | 121 +++++++++++++++++++++ lib/arel/engines/sql/predicates.rb | 37 +++++++ lib/arel/engines/sql/primitives.rb | 3 + lib/arel/engines/sql/primitives/attribute.rb | 17 +++ lib/arel/engines/sql/primitives/expression.rb | 7 ++ lib/arel/engines/sql/primitives/value.rb | 11 ++ lib/arel/engines/sql/relations.rb | 5 + lib/arel/engines/sql/relations/operations.rb | 2 + lib/arel/engines/sql/relations/operations/alias.rb | 5 + lib/arel/engines/sql/relations/operations/join.rb | 19 ++++ lib/arel/engines/sql/relations/relation.rb | 28 +++++ lib/arel/engines/sql/relations/table.rb | 36 ++++++ lib/arel/engines/sql/relations/utilities.rb | 3 + .../sql/relations/utilities/externalization.rb | 14 +++ lib/arel/engines/sql/relations/utilities/nil.rb | 6 + .../engines/sql/relations/utilities/recursion.rb | 13 +++ lib/arel/engines/sql/relations/writes.rb | 3 + lib/arel/engines/sql/relations/writes/delete.rb | 12 ++ lib/arel/engines/sql/relations/writes/insert.rb | 12 ++ lib/arel/engines/sql/relations/writes/update.rb | 14 +++ lib/arel/engines/sql/sql.rb | 7 ++ lib/arel/extensions.rb | 2 - lib/arel/extensions/array.rb | 8 -- lib/arel/extensions/nil_class.rb | 5 - lib/arel/extensions/object.rb | 8 -- lib/arel/extensions/range.rb | 9 -- lib/arel/predicates.rb | 15 --- lib/arel/primitives/attribute.rb | 12 -- lib/arel/primitives/expression.rb | 4 - lib/arel/primitives/value.rb | 13 --- lib/arel/relations.rb | 2 - lib/arel/relations/array.rb | 19 ---- lib/arel/relations/operations/alias.rb | 1 - lib/arel/relations/operations/join.rb | 16 --- lib/arel/relations/relation.rb | 32 +----- lib/arel/relations/table.rb | 36 ------ lib/arel/relations/utilities.rb | 2 - lib/arel/relations/utilities/externalization.rb | 10 -- lib/arel/relations/utilities/nil.rb | 3 - lib/arel/relations/utilities/recursion.rb | 13 --- lib/arel/relations/writes/delete.rb | 9 -- lib/arel/relations/writes/insert.rb | 9 -- lib/arel/relations/writes/update.rb | 11 -- lib/arel/sql.rb | 2 - lib/arel/sql/christener.rb | 13 --- lib/arel/sql/formatters.rb | 121 --------------------- 58 files changed, 489 insertions(+), 418 deletions(-) delete mode 100644 lib/arel/engine.rb create mode 100644 lib/arel/engines.rb create mode 100644 lib/arel/engines/array/array.rb create mode 100644 lib/arel/engines/array/relations/array.rb create mode 100644 lib/arel/engines/sql/christener.rb create mode 100644 lib/arel/engines/sql/engine.rb create mode 100644 lib/arel/engines/sql/extensions.rb create mode 100644 lib/arel/engines/sql/extensions/array.rb create mode 100644 lib/arel/engines/sql/extensions/nil_class.rb create mode 100644 lib/arel/engines/sql/extensions/object.rb create mode 100644 lib/arel/engines/sql/extensions/range.rb create mode 100644 lib/arel/engines/sql/formatters.rb create mode 100644 lib/arel/engines/sql/predicates.rb create mode 100644 lib/arel/engines/sql/primitives.rb create mode 100644 lib/arel/engines/sql/primitives/attribute.rb create mode 100644 lib/arel/engines/sql/primitives/expression.rb create mode 100644 lib/arel/engines/sql/primitives/value.rb create mode 100644 lib/arel/engines/sql/relations.rb create mode 100644 lib/arel/engines/sql/relations/operations.rb create mode 100644 lib/arel/engines/sql/relations/operations/alias.rb create mode 100644 lib/arel/engines/sql/relations/operations/join.rb create mode 100644 lib/arel/engines/sql/relations/relation.rb create mode 100644 lib/arel/engines/sql/relations/table.rb create mode 100644 lib/arel/engines/sql/relations/utilities.rb create mode 100644 lib/arel/engines/sql/relations/utilities/externalization.rb create mode 100644 lib/arel/engines/sql/relations/utilities/nil.rb create mode 100644 lib/arel/engines/sql/relations/utilities/recursion.rb create mode 100644 lib/arel/engines/sql/relations/writes.rb create mode 100644 lib/arel/engines/sql/relations/writes/delete.rb create mode 100644 lib/arel/engines/sql/relations/writes/insert.rb create mode 100644 lib/arel/engines/sql/relations/writes/update.rb create mode 100644 lib/arel/engines/sql/sql.rb delete mode 100644 lib/arel/extensions/nil_class.rb delete mode 100644 lib/arel/extensions/range.rb delete mode 100644 lib/arel/relations/array.rb delete mode 100644 lib/arel/relations/table.rb delete mode 100644 lib/arel/relations/utilities/recursion.rb delete mode 100644 lib/arel/sql.rb delete mode 100644 lib/arel/sql/christener.rb delete mode 100644 lib/arel/sql/formatters.rb (limited to 'lib') diff --git a/lib/arel.rb b/lib/arel.rb index 00bfa1e292..f22287fcc5 100644 --- a/lib/arel.rb +++ b/lib/arel.rb @@ -7,9 +7,8 @@ require 'active_record/connection_adapters/abstract/quoting' require 'arel/arel' require 'arel/extensions' -require 'arel/sql' require 'arel/predicates' require 'arel/relations' -require 'arel/engine' +require 'arel/engines' require 'arel/session' require 'arel/primitives' diff --git a/lib/arel/engine.rb b/lib/arel/engine.rb deleted file mode 100644 index 2bb4bbbd90..0000000000 --- a/lib/arel/engine.rb +++ /dev/null @@ -1,42 +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 - - module CRUD - def create(relation) - connection.insert(relation.to_sql) - end - - def read(relation) - results = connection.execute(relation.to_sql) - rows = [] - results.each do |row| - rows << attributes.zip(row).to_hash - end - rows - end - - def update(relation) - connection.update(relation.to_sql) - end - - def delete(relation) - connection.delete(relation.to_sql) - end - end - include CRUD - end -end diff --git a/lib/arel/engines.rb b/lib/arel/engines.rb new file mode 100644 index 0000000000..63a929528f --- /dev/null +++ b/lib/arel/engines.rb @@ -0,0 +1,2 @@ +require 'arel/engines/sql/sql' +require 'arel/engines/array/array' \ No newline at end of file diff --git a/lib/arel/engines/array/array.rb b/lib/arel/engines/array/array.rb new file mode 100644 index 0000000000..3a3a47308a --- /dev/null +++ b/lib/arel/engines/array/array.rb @@ -0,0 +1 @@ +require 'arel/engines/array/relations/array' \ No newline at end of file diff --git a/lib/arel/engines/array/relations/array.rb b/lib/arel/engines/array/relations/array.rb new file mode 100644 index 0000000000..dac65abbc2 --- /dev/null +++ b/lib/arel/engines/array/relations/array.rb @@ -0,0 +1,19 @@ +module Arel + class Array < Relation + include Recursion::BaseCase + + def initialize(array, attribute_names) + @array, @attribute_names = array, attribute_names + end + + def attributes + @attributes ||= @attribute_names.collect do |name| + Attribute.new(self, name.to_sym) + end + end + + def call(connection = nil) + @array.collect { |row| attributes.zip(row).to_hash } + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/christener.rb b/lib/arel/engines/sql/christener.rb new file mode 100644 index 0000000000..5883a75f41 --- /dev/null +++ b/lib/arel/engines/sql/christener.rb @@ -0,0 +1,13 @@ +module Arel + module Sql + class Christener + def name_for(relation) + @used_names ||= Hash.new(0) + (@relation_names ||= Hash.new do |hash, relation| + @used_names[name = relation.name] += 1 + hash[relation] = name + (@used_names[name] > 1 ? "_#{@used_names[name]}" : '') + end)[relation.table] + end + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/engine.rb b/lib/arel/engines/sql/engine.rb new file mode 100644 index 0000000000..e5d1a8b0ca --- /dev/null +++ b/lib/arel/engines/sql/engine.rb @@ -0,0 +1,41 @@ +module Arel + module Sql + 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 + + module CRUD + def create(relation) + connection.insert(relation.to_sql) + end + + def read(relation) + results = connection.execute(relation.to_sql) + rows = [] + results.each do |row| + rows << attributes.zip(row).to_hash + end + rows + end + + def update(relation) + connection.update(relation.to_sql) + end + + def delete(relation) + connection.delete(relation.to_sql) + end + end + include CRUD + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/extensions.rb b/lib/arel/engines/sql/extensions.rb new file mode 100644 index 0000000000..6f4ad32148 --- /dev/null +++ b/lib/arel/engines/sql/extensions.rb @@ -0,0 +1,4 @@ +require 'arel/engines/sql/extensions/object' +require 'arel/engines/sql/extensions/array' +require 'arel/engines/sql/extensions/range' +require 'arel/engines/sql/extensions/nil_class' \ No newline at end of file diff --git a/lib/arel/engines/sql/extensions/array.rb b/lib/arel/engines/sql/extensions/array.rb new file mode 100644 index 0000000000..1daa5abca7 --- /dev/null +++ b/lib/arel/engines/sql/extensions/array.rb @@ -0,0 +1,9 @@ +class Array + def to_sql(formatter = nil) + "(" + collect { |e| e.to_sql(formatter) }.join(', ') + ")" + end + + def inclusion_predicate_sql + "IN" + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/extensions/nil_class.rb b/lib/arel/engines/sql/extensions/nil_class.rb new file mode 100644 index 0000000000..729c4cada7 --- /dev/null +++ b/lib/arel/engines/sql/extensions/nil_class.rb @@ -0,0 +1,5 @@ +class NilClass + def equality_predicate_sql + 'IS' + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/extensions/object.rb b/lib/arel/engines/sql/extensions/object.rb new file mode 100644 index 0000000000..ef990eee2f --- /dev/null +++ b/lib/arel/engines/sql/extensions/object.rb @@ -0,0 +1,9 @@ +class Object + def to_sql(formatter) + formatter.scalar self + end + + def equality_predicate_sql + '=' + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/extensions/range.rb b/lib/arel/engines/sql/extensions/range.rb new file mode 100644 index 0000000000..d7329efe34 --- /dev/null +++ b/lib/arel/engines/sql/extensions/range.rb @@ -0,0 +1,9 @@ +class Range + def to_sql(formatter = nil) + formatter.range self.begin, self.end + end + + def inclusion_predicate_sql + "BETWEEN" + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/formatters.rb b/lib/arel/engines/sql/formatters.rb new file mode 100644 index 0000000000..f82ddf631f --- /dev/null +++ b/lib/arel/engines/sql/formatters.rb @@ -0,0 +1,121 @@ +module Arel + module Sql + class Formatter + attr_reader :environment + delegate :christener, :engine, :to => :environment + delegate :name_for, :to => :christener + delegate :quote_table_name, :quote_column_name, :quote, :to => :engine + + def initialize(environment) + @environment = environment + end + end + + class SelectClause < Formatter + def attribute(attribute) + # FIXME this should check that the column exists + if attribute.name.to_s =~ /^\w*$/ + "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" + (attribute.alias ? " AS #{quote(attribute.alias.to_s)}" : "") + else + attribute.name.to_s + (attribute.alias ? " AS #{quote(attribute.alias.to_s)}" : "") + end + end + + def expression(expression) + if expression.function_sql == "DISTINCT" + "#{expression.function_sql} #{expression.attribute.to_sql(self)}" + (expression.alias ? " AS #{quote_column_name(expression.alias)}" : '') + else + "#{expression.function_sql}(#{expression.attribute.to_sql(self)})" + (expression.alias ? " AS #{quote_column_name(expression.alias)}" : " AS #{expression.function_sql.to_s.downcase}_id") + end + end + + def select(select_sql, table) + "(#{select_sql}) AS #{quote_table_name(name_for(table))}" + end + + def value(value) + value + end + end + + class PassThrough < Formatter + def value(value) + value + end + end + + class WhereClause < PassThrough + end + + class OrderClause < PassThrough + def attribute(attribute) + "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" + end + end + + class GroupClause < PassThrough + def attribute(attribute) + "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" + end + end + + class WhereCondition < Formatter + def attribute(attribute) + "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" + end + + def expression(expression) + "#{expression.function_sql}(#{expression.attribute.to_sql(self)})" + end + + def value(value) + value.to_sql(self) + end + + def scalar(value, column = nil) + quote(value, column) + end + + def select(select_sql, table) + "(#{select_sql})" + end + end + + class SelectStatement < Formatter + def select(select_sql, table) + select_sql + end + end + + class TableReference < Formatter + def select(select_sql, table) + "(#{select_sql}) AS #{quote_table_name(name_for(table))}" + end + + def table(table) + if table.name =~ /^(\w|-)*$/ + quote_table_name(table.name) + (table.name != name_for(table) ? " AS " + quote_table_name(name_for(table)) : '') + else + table.name + (table.name != name_for(table) ? " AS " + (name_for(table)) : '') + end + end + end + + class Attribute < WhereCondition + def scalar(scalar) + quote(scalar, environment.column) + end + + def array(array) + "(" + array.collect { |e| e.to_sql(self) }.join(', ') + ")" + end + + def range(left, right) + "#{left} AND #{right}" + end + end + + class Value < WhereCondition + end + end +end diff --git a/lib/arel/engines/sql/predicates.rb b/lib/arel/engines/sql/predicates.rb new file mode 100644 index 0000000000..dfeddb2de1 --- /dev/null +++ b/lib/arel/engines/sql/predicates.rb @@ -0,0 +1,37 @@ +module Arel + class Binary < Predicate + def to_sql(formatter = nil) + "#{operand1.to_sql} #{predicate_sql} #{operand1.format(operand2)}" + end + end + + class Equality < Binary + def predicate_sql + operand2.equality_predicate_sql + end + end + + class GreaterThanOrEqualTo < Binary + def predicate_sql; '>=' end + end + + class GreaterThan < Binary + def predicate_sql; '>' end + end + + class LessThanOrEqualTo < Binary + def predicate_sql; '<=' end + end + + class LessThan < Binary + def predicate_sql; '<' end + end + + class Match < Binary + def predicate_sql; 'LIKE' end + end + + class In < Binary + def predicate_sql; operand2.inclusion_predicate_sql end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/primitives.rb b/lib/arel/engines/sql/primitives.rb new file mode 100644 index 0000000000..405b1ca803 --- /dev/null +++ b/lib/arel/engines/sql/primitives.rb @@ -0,0 +1,3 @@ +require 'arel/engines/sql/primitives/attribute' +require 'arel/engines/sql/primitives/value' +require 'arel/engines/sql/primitives/expression' \ No newline at end of file diff --git a/lib/arel/engines/sql/primitives/attribute.rb b/lib/arel/engines/sql/primitives/attribute.rb new file mode 100644 index 0000000000..48de690b6f --- /dev/null +++ b/lib/arel/engines/sql/primitives/attribute.rb @@ -0,0 +1,17 @@ +require 'set' + +module Arel + class Attribute + def column + original_relation.column_for(self) + end + + def format(object) + object.to_sql(Sql::Attribute.new(self)) + end + + def to_sql(formatter = Sql::WhereCondition.new(relation)) + formatter.attribute self + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/primitives/expression.rb b/lib/arel/engines/sql/primitives/expression.rb new file mode 100644 index 0000000000..24f6879848 --- /dev/null +++ b/lib/arel/engines/sql/primitives/expression.rb @@ -0,0 +1,7 @@ +module Arel + class Expression < Attribute + def to_sql(formatter = Sql::SelectClause.new(relation)) + formatter.expression self + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/primitives/value.rb b/lib/arel/engines/sql/primitives/value.rb new file mode 100644 index 0000000000..a44acc26e0 --- /dev/null +++ b/lib/arel/engines/sql/primitives/value.rb @@ -0,0 +1,11 @@ +module Arel + class Value + def to_sql(formatter = Sql::WhereCondition.new(relation)) + formatter.value value + end + + def format(object) + object.to_sql(Sql::Value.new(relation)) + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/relations.rb b/lib/arel/engines/sql/relations.rb new file mode 100644 index 0000000000..4de01b2691 --- /dev/null +++ b/lib/arel/engines/sql/relations.rb @@ -0,0 +1,5 @@ +require 'arel/engines/sql/relations/utilities' +require 'arel/engines/sql/relations/relation' +require 'arel/engines/sql/relations/operations' +require 'arel/engines/sql/relations/writes' +require 'arel/engines/sql/relations/table' \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/operations.rb b/lib/arel/engines/sql/relations/operations.rb new file mode 100644 index 0000000000..ff33fc6bc3 --- /dev/null +++ b/lib/arel/engines/sql/relations/operations.rb @@ -0,0 +1,2 @@ +require 'arel/engines/sql/relations/operations/alias' +require 'arel/engines/sql/relations/operations/join' diff --git a/lib/arel/engines/sql/relations/operations/alias.rb b/lib/arel/engines/sql/relations/operations/alias.rb new file mode 100644 index 0000000000..32c9911a69 --- /dev/null +++ b/lib/arel/engines/sql/relations/operations/alias.rb @@ -0,0 +1,5 @@ +module Arel + class Alias < Compound + include Recursion::BaseCase + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/operations/join.rb b/lib/arel/engines/sql/relations/operations/join.rb new file mode 100644 index 0000000000..be21119bc9 --- /dev/null +++ b/lib/arel/engines/sql/relations/operations/join.rb @@ -0,0 +1,19 @@ +module Arel + class Join < Relation + 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 + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/relation.rb b/lib/arel/engines/sql/relations/relation.rb new file mode 100644 index 0000000000..5fd4121176 --- /dev/null +++ b/lib/arel/engines/sql/relations/relation.rb @@ -0,0 +1,28 @@ +module Arel + class Relation + def to_sql(formatter = Sql::SelectStatement.new(self)) + formatter.select select_sql, self + end + + def select_sql + [ + "SELECT #{attributes.collect { |a| a.to_sql(Sql::SelectClause.new(self)) }.join(', ')}", + "FROM #{table_sql(Sql::TableReference.new(self))}", + (joins(self) unless joins(self).blank? ), + ("WHERE #{wheres .collect { |w| w.to_sql(Sql::WhereClause.new(self)) }.join("\n\tAND ")}" unless wheres.blank? ), + ("GROUP BY #{groupings.collect { |g| g.to_sql(Sql::GroupClause.new(self)) }.join(', ')}" unless groupings.blank? ), + ("ORDER BY #{orders .collect { |o| o.to_sql(Sql::OrderClause.new(self)) }.join(', ')}" unless orders.blank? ), + ("LIMIT #{taken}" unless taken.blank? ), + ("OFFSET #{skipped}" unless skipped.blank? ) + ].compact.join("\n") + end + + def inclusion_predicate_sql + "IN" + end + + def christener + @christener ||= Sql::Christener.new + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/table.rb b/lib/arel/engines/sql/relations/table.rb new file mode 100644 index 0000000000..0433abbbb2 --- /dev/null +++ b/lib/arel/engines/sql/relations/table.rb @@ -0,0 +1,36 @@ +module Arel + class Table < Relation + include Recursion::BaseCase + + cattr_accessor :engine + attr_reader :name, :engine + hash_on :name + + def initialize(name, engine = Table.engine) + @name, @engine = name.to_s, engine + end + + def attributes + @attributes ||= columns.collect do |column| + Attribute.new(self, column.name.to_sym) + end + end + + def column_for(attribute) + has_attribute?(attribute) and columns.detect { |c| c.name == attribute.name.to_s } + end + + def columns + @columns ||= engine.columns(name, "#{name} Columns") + end + + def reset + @attributes = @columns = nil + end + + def ==(other) + Table === other and + name == other.name + end + end +end diff --git a/lib/arel/engines/sql/relations/utilities.rb b/lib/arel/engines/sql/relations/utilities.rb new file mode 100644 index 0000000000..a1451ed448 --- /dev/null +++ b/lib/arel/engines/sql/relations/utilities.rb @@ -0,0 +1,3 @@ +require 'arel/engines/sql/relations/utilities/recursion' +require 'arel/engines/sql/relations/utilities/externalization' +require 'arel/engines/sql/relations/utilities/nil' diff --git a/lib/arel/engines/sql/relations/utilities/externalization.rb b/lib/arel/engines/sql/relations/utilities/externalization.rb new file mode 100644 index 0000000000..1ac6f2de8e --- /dev/null +++ b/lib/arel/engines/sql/relations/utilities/externalization.rb @@ -0,0 +1,14 @@ +module Arel + class Externalization < Compound + include Recursion::BaseCase + + def table_sql(formatter = Sql::TableReference.new(relation)) + formatter.select relation.select_sql, self + end + + # REMOVEME + def name + relation.name + '_external' + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/utilities/nil.rb b/lib/arel/engines/sql/relations/utilities/nil.rb new file mode 100644 index 0000000000..77534b25ad --- /dev/null +++ b/lib/arel/engines/sql/relations/utilities/nil.rb @@ -0,0 +1,6 @@ +module Arel + class Nil < Relation + def table_sql(formatter = nil); '' end + def name; '' end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/utilities/recursion.rb b/lib/arel/engines/sql/relations/utilities/recursion.rb new file mode 100644 index 0000000000..848b059507 --- /dev/null +++ b/lib/arel/engines/sql/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/engines/sql/relations/writes.rb b/lib/arel/engines/sql/relations/writes.rb new file mode 100644 index 0000000000..dcadc326d9 --- /dev/null +++ b/lib/arel/engines/sql/relations/writes.rb @@ -0,0 +1,3 @@ +require 'arel/engines/sql/relations/writes/delete' +require 'arel/engines/sql/relations/writes/insert' +require 'arel/engines/sql/relations/writes/update' diff --git a/lib/arel/engines/sql/relations/writes/delete.rb b/lib/arel/engines/sql/relations/writes/delete.rb new file mode 100644 index 0000000000..b22ee51e24 --- /dev/null +++ b/lib/arel/engines/sql/relations/writes/delete.rb @@ -0,0 +1,12 @@ +module Arel + class Deletion < Compound + 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 + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/writes/insert.rb b/lib/arel/engines/sql/relations/writes/insert.rb new file mode 100644 index 0000000000..aac9c87a5b --- /dev/null +++ b/lib/arel/engines/sql/relations/writes/insert.rb @@ -0,0 +1,12 @@ +module Arel + class Insert < Compound + def to_sql(formatter = nil) + [ + "INSERT", + "INTO #{table_sql}", + "(#{record.keys.collect { |key| engine.quote_column_name(key.name) }.join(', ')})", + "VALUES (#{record.collect { |key, value| key.format(value) }.join(', ')})" + ].join("\n") + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/writes/update.rb b/lib/arel/engines/sql/relations/writes/update.rb new file mode 100644 index 0000000000..3e35a0d5cc --- /dev/null +++ b/lib/arel/engines/sql/relations/writes/update.rb @@ -0,0 +1,14 @@ +module Arel + class Update < Compound + def to_sql(formatter = nil) + [ + "UPDATE #{table_sql} SET", + assignments.collect do |attribute, value| + "#{engine.quote_column_name(attribute.name)} = #{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 + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/sql.rb b/lib/arel/engines/sql/sql.rb new file mode 100644 index 0000000000..aed1fd861e --- /dev/null +++ b/lib/arel/engines/sql/sql.rb @@ -0,0 +1,7 @@ +require 'arel/engines/sql/engine' +require 'arel/engines/sql/relations' +require 'arel/engines/sql/primitives' +require 'arel/engines/sql/predicates' +require 'arel/engines/sql/formatters' +require 'arel/engines/sql/extensions' +require 'arel/engines/sql/christener' \ No newline at end of file diff --git a/lib/arel/extensions.rb b/lib/arel/extensions.rb index 160cf36e5b..299ba0631c 100644 --- a/lib/arel/extensions.rb +++ b/lib/arel/extensions.rb @@ -2,5 +2,3 @@ require 'arel/extensions/object' require 'arel/extensions/class' require 'arel/extensions/array' require 'arel/extensions/hash' -require 'arel/extensions/range' -require 'arel/extensions/nil_class' \ No newline at end of file diff --git a/lib/arel/extensions/array.rb b/lib/arel/extensions/array.rb index 793c06aad8..5b6d6d6abd 100644 --- a/lib/arel/extensions/array.rb +++ b/lib/arel/extensions/array.rb @@ -2,12 +2,4 @@ class Array def to_hash Hash[*flatten] end - - def to_sql(formatter = nil) - "(" + collect { |e| e.to_sql(formatter) }.join(', ') + ")" - end - - def inclusion_predicate_sql - "IN" - end end \ No newline at end of file diff --git a/lib/arel/extensions/nil_class.rb b/lib/arel/extensions/nil_class.rb deleted file mode 100644 index 729c4cada7..0000000000 --- a/lib/arel/extensions/nil_class.rb +++ /dev/null @@ -1,5 +0,0 @@ -class NilClass - def equality_predicate_sql - 'IS' - end -end \ No newline at end of file diff --git a/lib/arel/extensions/object.rb b/lib/arel/extensions/object.rb index 14e2f82ce5..d626407dcb 100644 --- a/lib/arel/extensions/object.rb +++ b/lib/arel/extensions/object.rb @@ -7,14 +7,6 @@ class Object bind(relation) end - def to_sql(formatter) - formatter.scalar self - end - - def equality_predicate_sql - '=' - end - def metaclass class << self self diff --git a/lib/arel/extensions/range.rb b/lib/arel/extensions/range.rb deleted file mode 100644 index d7329efe34..0000000000 --- a/lib/arel/extensions/range.rb +++ /dev/null @@ -1,9 +0,0 @@ -class Range - def to_sql(formatter = nil) - formatter.range self.begin, self.end - end - - def inclusion_predicate_sql - "BETWEEN" - end -end \ No newline at end of file diff --git a/lib/arel/predicates.rb b/lib/arel/predicates.rb index b639022b4e..aa206d4e96 100644 --- a/lib/arel/predicates.rb +++ b/lib/arel/predicates.rb @@ -22,11 +22,6 @@ module Arel def bind(relation) self.class.new(operand1.find_correlate_in(relation), operand2.find_correlate_in(relation)) end - - def to_sql(formatter = nil) - "#{operand1.to_sql} #{predicate_sql} #{operand1.format(operand2)}" - end - alias_method :to_s, :to_sql end class CompoundPredicate < Binary @@ -49,33 +44,23 @@ module Arel ((operand1 == other.operand1 and operand2 == other.operand2) or (operand1 == other.operand2 and operand2 == other.operand1)) end - - def predicate_sql - operand2.equality_predicate_sql - end end class GreaterThanOrEqualTo < Binary - def predicate_sql; '>=' end end class GreaterThan < Binary - def predicate_sql; '>' end end class LessThanOrEqualTo < Binary - def predicate_sql; '<=' end end class LessThan < Binary - def predicate_sql; '<' end end class Match < Binary - def predicate_sql; 'LIKE' end end class In < Binary - def predicate_sql; operand2.inclusion_predicate_sql end end end diff --git a/lib/arel/primitives/attribute.rb b/lib/arel/primitives/attribute.rb index 6cb558d8ce..5e216770e4 100644 --- a/lib/arel/primitives/attribute.rb +++ b/lib/arel/primitives/attribute.rb @@ -18,18 +18,6 @@ module Arel false end - def column - original_relation.column_for(self) - end - - def format(object) - object.to_sql(Sql::Attribute.new(self)) - end - - def to_sql(formatter = Sql::WhereCondition.new(relation)) - formatter.attribute self - end - module Transformations def self.included(klass) klass.send :alias_method, :eql?, :== diff --git a/lib/arel/primitives/expression.rb b/lib/arel/primitives/expression.rb index 836f014745..b67a5e1f8e 100644 --- a/lib/arel/primitives/expression.rb +++ b/lib/arel/primitives/expression.rb @@ -9,10 +9,6 @@ module Arel @attribute, @function_sql, @alias, @ancestor = attribute, function_sql, aliaz, ancestor end - def to_sql(formatter = Sql::SelectClause.new(relation)) - formatter.expression self - end - def aggregation? true end diff --git a/lib/arel/primitives/value.rb b/lib/arel/primitives/value.rb index 9c6e518a95..91c4045507 100644 --- a/lib/arel/primitives/value.rb +++ b/lib/arel/primitives/value.rb @@ -4,19 +4,6 @@ module Arel deriving :initialize, :== delegate :inclusion_predicate_sql, :equality_predicate_sql, :to => :value - - def to_sql(formatter = Sql::WhereCondition.new(relation)) - if value =~ /^\(.*\)$/ - value - else - formatter.value value - end - end - - def format(object) - object.to_sql(Sql::Value.new(relation)) - end - def bind(relation) Value.new(value, relation) end diff --git a/lib/arel/relations.rb b/lib/arel/relations.rb index fd758ed15d..f97c35e56e 100644 --- a/lib/arel/relations.rb +++ b/lib/arel/relations.rb @@ -1,6 +1,4 @@ require 'arel/relations/relation' require 'arel/relations/utilities' -require 'arel/relations/table' -require 'arel/relations/array' require 'arel/relations/writes' require 'arel/relations/operations' \ No newline at end of file diff --git a/lib/arel/relations/array.rb b/lib/arel/relations/array.rb deleted file mode 100644 index dac65abbc2..0000000000 --- a/lib/arel/relations/array.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Arel - class Array < Relation - include Recursion::BaseCase - - def initialize(array, attribute_names) - @array, @attribute_names = array, attribute_names - end - - def attributes - @attributes ||= @attribute_names.collect do |name| - Attribute.new(self, name.to_sym) - end - end - - def call(connection = nil) - @array.collect { |row| attributes.zip(row).to_hash } - end - end -end \ No newline at end of file diff --git a/lib/arel/relations/operations/alias.rb b/lib/arel/relations/operations/alias.rb index 8ed33fc597..67837f6a75 100644 --- a/lib/arel/relations/operations/alias.rb +++ b/lib/arel/relations/operations/alias.rb @@ -1,6 +1,5 @@ module Arel class Alias < Compound - include Recursion::BaseCase attributes :relation deriving :initialize alias_method :==, :equal? diff --git a/lib/arel/relations/operations/join.rb b/lib/arel/relations/operations/join.rb index 8fe89358d8..8e19254378 100644 --- a/lib/arel/relations/operations/join.rb +++ b/lib/arel/relations/operations/join.rb @@ -9,22 +9,6 @@ module Arel @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) } diff --git a/lib/arel/relations/relation.rb b/lib/arel/relations/relation.rb index ef295dfdd7..20badaf165 100644 --- a/lib/arel/relations/relation.rb +++ b/lib/arel/relations/relation.rb @@ -6,32 +6,6 @@ module Arel Session.new end - def count - @count = "COUNT(*) AS count_all" - end - - def to_sql(formatter = Sql::SelectStatement.new(self)) - formatter.select select_sql, self - end - alias_method :to_s, :to_sql - - def select_sql - [ - "SELECT #{@count} #{attributes.collect { |a| a.to_sql(Sql::SelectClause.new(self)) }.join(', ') unless @count}", - "FROM #{table_sql(Sql::TableReference.new(self))}", - (joins(self) unless joins(self).blank? ), - ("WHERE #{wheres .collect { |w| w.to_sql(Sql::WhereClause.new(self)) }.join("\n\tAND ")}" unless wheres.blank? ), - ("GROUP BY #{groupings.collect { |g| g.to_sql(Sql::GroupClause.new(self)) }.join(', ')}" unless groupings.blank? ), - ("ORDER BY #{orders .collect { |o| o.to_sql(Sql::OrderClause.new(self)) }.join(', ')}" unless orders.blank? ), - ("LIMIT #{taken}" unless taken.blank? ), - ("OFFSET #{skipped}" unless skipped.blank? ) - ].compact.join("\n") - end - - def inclusion_predicate_sql - "IN" - end - def call engine.read(self) end @@ -44,10 +18,6 @@ module Arel self end - def christener - @christener ||= Sql::Christener.new - end - module Enumerable include ::Enumerable @@ -155,7 +125,7 @@ module Arel def orders; [] end def inserts; [] end def groupings; [] end - def joins(formatter = nil); nil end + def joins(formatter = nil); nil end # FIXME def taken; nil end def skipped; nil end end diff --git a/lib/arel/relations/table.rb b/lib/arel/relations/table.rb deleted file mode 100644 index 0433abbbb2..0000000000 --- a/lib/arel/relations/table.rb +++ /dev/null @@ -1,36 +0,0 @@ -module Arel - class Table < Relation - include Recursion::BaseCase - - cattr_accessor :engine - attr_reader :name, :engine - hash_on :name - - def initialize(name, engine = Table.engine) - @name, @engine = name.to_s, engine - end - - def attributes - @attributes ||= columns.collect do |column| - Attribute.new(self, column.name.to_sym) - end - end - - def column_for(attribute) - has_attribute?(attribute) and columns.detect { |c| c.name == attribute.name.to_s } - end - - def columns - @columns ||= engine.columns(name, "#{name} Columns") - end - - def reset - @attributes = @columns = nil - end - - def ==(other) - Table === other and - name == other.name - end - end -end diff --git a/lib/arel/relations/utilities.rb b/lib/arel/relations/utilities.rb index 454d455359..fbd949ef0c 100644 --- a/lib/arel/relations/utilities.rb +++ b/lib/arel/relations/utilities.rb @@ -1,5 +1,3 @@ require 'arel/relations/utilities/compound' -require 'arel/relations/utilities/recursion' require 'arel/relations/utilities/nil' require 'arel/relations/utilities/externalization' -require 'arel/relations/utilities/recursion' \ No newline at end of file diff --git a/lib/arel/relations/utilities/externalization.rb b/lib/arel/relations/utilities/externalization.rb index 3b9b2296dc..bd067f2304 100644 --- a/lib/arel/relations/utilities/externalization.rb +++ b/lib/arel/relations/utilities/externalization.rb @@ -2,24 +2,14 @@ module Arel class Externalization < Compound attributes :relation deriving :initialize, :== - include Recursion::BaseCase 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 - - # REMOVEME - def name - relation.name + '_external' - end end class Relation diff --git a/lib/arel/relations/utilities/nil.rb b/lib/arel/relations/utilities/nil.rb index 56cf395d2c..6a9d678c45 100644 --- a/lib/arel/relations/utilities/nil.rb +++ b/lib/arel/relations/utilities/nil.rb @@ -3,8 +3,5 @@ require 'singleton' module Arel class Nil < Relation include Singleton - - def table_sql(formatter = nil); '' end - def name; '' end end end diff --git a/lib/arel/relations/utilities/recursion.rb b/lib/arel/relations/utilities/recursion.rb deleted file mode 100644 index 848b059507..0000000000 --- a/lib/arel/relations/utilities/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/writes/delete.rb b/lib/arel/relations/writes/delete.rb index 0a04454e7f..a94067c7fa 100644 --- a/lib/arel/relations/writes/delete.rb +++ b/lib/arel/relations/writes/delete.rb @@ -3,15 +3,6 @@ module Arel attributes :relation deriving :initialize, :== - 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 engine.delete(self) end diff --git a/lib/arel/relations/writes/insert.rb b/lib/arel/relations/writes/insert.rb index d05bd9cdc8..6d85e9769a 100644 --- a/lib/arel/relations/writes/insert.rb +++ b/lib/arel/relations/writes/insert.rb @@ -7,15 +7,6 @@ module Arel @relation, @record = relation, record.bind(relation) end - def to_sql(formatter = nil) - [ - "INSERT", - "INTO #{table_sql}", - "(#{record.keys.map { |key| engine.quote_column_name(key.name) }.join(', ')})", - "VALUES (#{record.map { |key, value| key.format(value) }.join(', ')})" - ].join("\n") - end - def call engine.create(self) end diff --git a/lib/arel/relations/writes/update.rb b/lib/arel/relations/writes/update.rb index fd0aadb479..e647218a80 100644 --- a/lib/arel/relations/writes/update.rb +++ b/lib/arel/relations/writes/update.rb @@ -7,17 +7,6 @@ module Arel @relation, @assignments = relation, assignments end - def to_sql(formatter = nil) - [ - "UPDATE #{table_sql} SET", - assignments.collect do |attribute, value| - "#{engine.quote_column_name(attribute.name)} = #{attribute.format(value)}" - end.join(",\n"), - ("WHERE #{wheres.map(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ), - ("LIMIT #{taken}" unless taken.blank? ) - ].join("\n") - end - def call engine.update(self) end diff --git a/lib/arel/sql.rb b/lib/arel/sql.rb deleted file mode 100644 index 7e7dd0a80f..0000000000 --- a/lib/arel/sql.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'arel/sql/formatters' -require 'arel/sql/christener' \ No newline at end of file diff --git a/lib/arel/sql/christener.rb b/lib/arel/sql/christener.rb deleted file mode 100644 index 5883a75f41..0000000000 --- a/lib/arel/sql/christener.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Arel - module Sql - class Christener - def name_for(relation) - @used_names ||= Hash.new(0) - (@relation_names ||= Hash.new do |hash, relation| - @used_names[name = relation.name] += 1 - hash[relation] = name + (@used_names[name] > 1 ? "_#{@used_names[name]}" : '') - end)[relation.table] - end - end - end -end \ No newline at end of file diff --git a/lib/arel/sql/formatters.rb b/lib/arel/sql/formatters.rb deleted file mode 100644 index f82ddf631f..0000000000 --- a/lib/arel/sql/formatters.rb +++ /dev/null @@ -1,121 +0,0 @@ -module Arel - module Sql - class Formatter - attr_reader :environment - delegate :christener, :engine, :to => :environment - delegate :name_for, :to => :christener - delegate :quote_table_name, :quote_column_name, :quote, :to => :engine - - def initialize(environment) - @environment = environment - end - end - - class SelectClause < Formatter - def attribute(attribute) - # FIXME this should check that the column exists - if attribute.name.to_s =~ /^\w*$/ - "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" + (attribute.alias ? " AS #{quote(attribute.alias.to_s)}" : "") - else - attribute.name.to_s + (attribute.alias ? " AS #{quote(attribute.alias.to_s)}" : "") - end - end - - def expression(expression) - if expression.function_sql == "DISTINCT" - "#{expression.function_sql} #{expression.attribute.to_sql(self)}" + (expression.alias ? " AS #{quote_column_name(expression.alias)}" : '') - else - "#{expression.function_sql}(#{expression.attribute.to_sql(self)})" + (expression.alias ? " AS #{quote_column_name(expression.alias)}" : " AS #{expression.function_sql.to_s.downcase}_id") - end - end - - def select(select_sql, table) - "(#{select_sql}) AS #{quote_table_name(name_for(table))}" - end - - def value(value) - value - end - end - - class PassThrough < Formatter - def value(value) - value - end - end - - class WhereClause < PassThrough - end - - class OrderClause < PassThrough - def attribute(attribute) - "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" - end - end - - class GroupClause < PassThrough - def attribute(attribute) - "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" - end - end - - class WhereCondition < Formatter - def attribute(attribute) - "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" - end - - def expression(expression) - "#{expression.function_sql}(#{expression.attribute.to_sql(self)})" - end - - def value(value) - value.to_sql(self) - end - - def scalar(value, column = nil) - quote(value, column) - end - - def select(select_sql, table) - "(#{select_sql})" - end - end - - class SelectStatement < Formatter - def select(select_sql, table) - select_sql - end - end - - class TableReference < Formatter - def select(select_sql, table) - "(#{select_sql}) AS #{quote_table_name(name_for(table))}" - end - - def table(table) - if table.name =~ /^(\w|-)*$/ - quote_table_name(table.name) + (table.name != name_for(table) ? " AS " + quote_table_name(name_for(table)) : '') - else - table.name + (table.name != name_for(table) ? " AS " + (name_for(table)) : '') - end - end - end - - class Attribute < WhereCondition - def scalar(scalar) - quote(scalar, environment.column) - end - - def array(array) - "(" + array.collect { |e| e.to_sql(self) }.join(', ') + ")" - end - - def range(left, right) - "#{left} AND #{right}" - end - end - - class Value < WhereCondition - end - end -end -- cgit v1.2.3 From 7032a50297fce4d7724d1735e81e5df5fd919e71 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 14:31:04 -0400 Subject: reorganized file structures Conflicts: lib/arel.rb lib/arel/arel.rb lib/arel/engines/memory/predicates.rb lib/arel/engines/memory/relations/array.rb lib/arel/engines/sql/relations/table.rb --- lib/arel.rb | 6 +- lib/arel/algebra.rb | 4 + lib/arel/algebra/extensions.rb | 4 + lib/arel/algebra/extensions/array.rb | 5 + lib/arel/algebra/extensions/class.rb | 37 ++++++ lib/arel/algebra/extensions/hash.rb | 7 ++ lib/arel/algebra/extensions/object.rb | 15 +++ lib/arel/algebra/extensions/pathname.rb | 5 + lib/arel/algebra/predicates.rb | 45 +++++++ lib/arel/algebra/primitives.rb | 4 + lib/arel/algebra/primitives/attribute.rb | 133 ++++++++++++++++++++ lib/arel/algebra/primitives/expression.rb | 31 +++++ lib/arel/algebra/primitives/value.rb | 19 +++ lib/arel/algebra/relations.rb | 15 +++ lib/arel/algebra/relations/operations/alias.rb | 7 ++ lib/arel/algebra/relations/operations/group.rb | 15 +++ lib/arel/algebra/relations/operations/join.rb | 41 +++++++ lib/arel/algebra/relations/operations/order.rb | 16 +++ lib/arel/algebra/relations/operations/project.rb | 19 +++ lib/arel/algebra/relations/operations/skip.rb | 10 ++ lib/arel/algebra/relations/operations/take.rb | 10 ++ lib/arel/algebra/relations/operations/where.rb | 16 +++ lib/arel/algebra/relations/relation.rb | 134 +++++++++++++++++++++ lib/arel/algebra/relations/utilities/compound.rb | 18 +++ .../algebra/relations/utilities/externalization.rb | 24 ++++ lib/arel/algebra/relations/utilities/nil.rb | 7 ++ lib/arel/algebra/relations/writes/delete.rb | 10 ++ lib/arel/algebra/relations/writes/insert.rb | 14 +++ lib/arel/algebra/relations/writes/update.rb | 14 +++ lib/arel/arel.rb | 3 - lib/arel/engines.rb | 4 +- lib/arel/engines/array/array.rb | 1 - lib/arel/engines/array/relations/array.rb | 19 --- lib/arel/engines/memory.rb | 4 + lib/arel/engines/memory/engine.rb | 12 ++ lib/arel/engines/memory/predicates.rb | 58 +++++++++ lib/arel/engines/memory/primitives.rb | 2 + lib/arel/engines/memory/primitives/attribute.rb | 7 ++ lib/arel/engines/memory/primitives/value.rb | 7 ++ lib/arel/engines/memory/relations.rb | 2 + lib/arel/engines/memory/relations/array.rb | 21 ++++ .../engines/memory/relations/operations/where.rb | 7 ++ lib/arel/engines/sql.rb | 7 ++ lib/arel/engines/sql/primitives/attribute.rb | 2 - lib/arel/engines/sql/relations.rb | 13 +- lib/arel/engines/sql/relations/operations.rb | 2 - lib/arel/engines/sql/relations/table.rb | 5 + lib/arel/engines/sql/relations/utilities.rb | 3 - lib/arel/engines/sql/relations/writes.rb | 3 - lib/arel/engines/sql/sql.rb | 7 -- lib/arel/extensions.rb | 4 - lib/arel/extensions/array.rb | 5 - lib/arel/extensions/class.rb | 37 ------ lib/arel/extensions/hash.rb | 7 -- lib/arel/extensions/object.rb | 15 --- lib/arel/predicates.rb | 66 ---------- lib/arel/primitives.rb | 4 - lib/arel/primitives/attribute.rb | 133 -------------------- lib/arel/primitives/expression.rb | 31 ----- lib/arel/primitives/value.rb | 19 --- lib/arel/relations.rb | 4 - lib/arel/relations/operations.rb | 8 -- lib/arel/relations/operations/alias.rb | 7 -- lib/arel/relations/operations/group.rb | 15 --- lib/arel/relations/operations/join.rb | 41 ------- lib/arel/relations/operations/order.rb | 16 --- lib/arel/relations/operations/project.rb | 19 --- lib/arel/relations/operations/skip.rb | 10 -- lib/arel/relations/operations/take.rb | 10 -- lib/arel/relations/operations/where.rb | 16 --- lib/arel/relations/relation.rb | 134 --------------------- lib/arel/relations/utilities.rb | 3 - lib/arel/relations/utilities/compound.rb | 18 --- lib/arel/relations/utilities/externalization.rb | 24 ---- lib/arel/relations/utilities/nil.rb | 7 -- lib/arel/relations/writes.rb | 3 - lib/arel/relations/writes/delete.rb | 10 -- lib/arel/relations/writes/insert.rb | 14 --- lib/arel/relations/writes/update.rb | 14 --- lib/arel/session.rb | 2 - 80 files changed, 823 insertions(+), 747 deletions(-) create mode 100644 lib/arel/algebra.rb create mode 100644 lib/arel/algebra/extensions.rb create mode 100644 lib/arel/algebra/extensions/array.rb create mode 100644 lib/arel/algebra/extensions/class.rb create mode 100644 lib/arel/algebra/extensions/hash.rb create mode 100644 lib/arel/algebra/extensions/object.rb create mode 100644 lib/arel/algebra/extensions/pathname.rb create mode 100644 lib/arel/algebra/predicates.rb create mode 100644 lib/arel/algebra/primitives.rb create mode 100644 lib/arel/algebra/primitives/attribute.rb create mode 100644 lib/arel/algebra/primitives/expression.rb create mode 100644 lib/arel/algebra/primitives/value.rb create mode 100644 lib/arel/algebra/relations.rb create mode 100644 lib/arel/algebra/relations/operations/alias.rb create mode 100644 lib/arel/algebra/relations/operations/group.rb create mode 100644 lib/arel/algebra/relations/operations/join.rb create mode 100644 lib/arel/algebra/relations/operations/order.rb create mode 100644 lib/arel/algebra/relations/operations/project.rb create mode 100644 lib/arel/algebra/relations/operations/skip.rb create mode 100644 lib/arel/algebra/relations/operations/take.rb create mode 100644 lib/arel/algebra/relations/operations/where.rb create mode 100644 lib/arel/algebra/relations/relation.rb create mode 100644 lib/arel/algebra/relations/utilities/compound.rb create mode 100644 lib/arel/algebra/relations/utilities/externalization.rb create mode 100644 lib/arel/algebra/relations/utilities/nil.rb create mode 100644 lib/arel/algebra/relations/writes/delete.rb create mode 100644 lib/arel/algebra/relations/writes/insert.rb create mode 100644 lib/arel/algebra/relations/writes/update.rb delete mode 100644 lib/arel/arel.rb delete mode 100644 lib/arel/engines/array/array.rb delete mode 100644 lib/arel/engines/array/relations/array.rb create mode 100644 lib/arel/engines/memory.rb create mode 100644 lib/arel/engines/memory/engine.rb create mode 100644 lib/arel/engines/memory/predicates.rb create mode 100644 lib/arel/engines/memory/primitives.rb create mode 100644 lib/arel/engines/memory/primitives/attribute.rb create mode 100644 lib/arel/engines/memory/primitives/value.rb create mode 100644 lib/arel/engines/memory/relations.rb create mode 100644 lib/arel/engines/memory/relations/array.rb create mode 100644 lib/arel/engines/memory/relations/operations/where.rb create mode 100644 lib/arel/engines/sql.rb delete mode 100644 lib/arel/engines/sql/relations/operations.rb delete mode 100644 lib/arel/engines/sql/relations/utilities.rb delete mode 100644 lib/arel/engines/sql/relations/writes.rb delete mode 100644 lib/arel/engines/sql/sql.rb delete mode 100644 lib/arel/extensions.rb delete mode 100644 lib/arel/extensions/array.rb delete mode 100644 lib/arel/extensions/class.rb delete mode 100644 lib/arel/extensions/hash.rb delete mode 100644 lib/arel/extensions/object.rb delete mode 100644 lib/arel/predicates.rb delete mode 100644 lib/arel/primitives.rb delete mode 100644 lib/arel/primitives/attribute.rb delete mode 100644 lib/arel/primitives/expression.rb delete mode 100644 lib/arel/primitives/value.rb delete mode 100644 lib/arel/relations.rb delete mode 100644 lib/arel/relations/operations.rb delete mode 100644 lib/arel/relations/operations/alias.rb delete mode 100644 lib/arel/relations/operations/group.rb delete mode 100644 lib/arel/relations/operations/join.rb delete mode 100644 lib/arel/relations/operations/order.rb delete mode 100644 lib/arel/relations/operations/project.rb delete mode 100644 lib/arel/relations/operations/skip.rb delete mode 100644 lib/arel/relations/operations/take.rb delete mode 100644 lib/arel/relations/operations/where.rb delete mode 100644 lib/arel/relations/relation.rb delete mode 100644 lib/arel/relations/utilities.rb delete mode 100644 lib/arel/relations/utilities/compound.rb delete mode 100644 lib/arel/relations/utilities/externalization.rb delete mode 100644 lib/arel/relations/utilities/nil.rb delete mode 100644 lib/arel/relations/writes.rb delete mode 100644 lib/arel/relations/writes/delete.rb delete mode 100644 lib/arel/relations/writes/insert.rb delete mode 100644 lib/arel/relations/writes/update.rb (limited to 'lib') diff --git a/lib/arel.rb b/lib/arel.rb index f22287fcc5..fcca60758e 100644 --- a/lib/arel.rb +++ b/lib/arel.rb @@ -5,10 +5,6 @@ require 'activesupport' require 'activerecord' require 'active_record/connection_adapters/abstract/quoting' -require 'arel/arel' -require 'arel/extensions' -require 'arel/predicates' -require 'arel/relations' +require 'arel/algebra' require 'arel/engines' require 'arel/session' -require 'arel/primitives' diff --git a/lib/arel/algebra.rb b/lib/arel/algebra.rb new file mode 100644 index 0000000000..f27882a343 --- /dev/null +++ b/lib/arel/algebra.rb @@ -0,0 +1,4 @@ +require 'arel/algebra/extensions' +require 'arel/algebra/predicates' +require 'arel/algebra/relations' +require 'arel/algebra/primitives' \ No newline at end of file diff --git a/lib/arel/algebra/extensions.rb b/lib/arel/algebra/extensions.rb new file mode 100644 index 0000000000..5338fee989 --- /dev/null +++ b/lib/arel/algebra/extensions.rb @@ -0,0 +1,4 @@ +require 'arel/algebra/extensions/object' +require 'arel/algebra/extensions/class' +require 'arel/algebra/extensions/array' +require 'arel/algebra/extensions/hash' diff --git a/lib/arel/algebra/extensions/array.rb b/lib/arel/algebra/extensions/array.rb new file mode 100644 index 0000000000..5b6d6d6abd --- /dev/null +++ b/lib/arel/algebra/extensions/array.rb @@ -0,0 +1,5 @@ +class Array + def to_hash + Hash[*flatten] + end +end \ No newline at end of file diff --git a/lib/arel/algebra/extensions/class.rb b/lib/arel/algebra/extensions/class.rb new file mode 100644 index 0000000000..f37898e7d7 --- /dev/null +++ b/lib/arel/algebra/extensions/class.rb @@ -0,0 +1,37 @@ +class Class + def attributes(*attrs) + @attributes = attrs + attr_reader *attrs + end + + def deriving(*methods) + methods.each { |m| derive m } + end + + def derive(method_name) + methods = { + :initialize => " + def #{method_name}(#{@attributes.join(',')}) + #{@attributes.collect { |a| "@#{a} = #{a}" }.join("\n")} + end + ", + :== => " + def ==(other) + #{name} === other && + #{@attributes.collect { |a| "@#{a} == other.#{a}" }.join(" &&\n")} + end + " + } + class_eval methods[method_name], __FILE__, __LINE__ + end + + def hash_on(delegatee) + define_method :eql? do |other| + self == other + end + + define_method :hash do + @hash ||= delegatee.hash + end + end +end \ No newline at end of file diff --git a/lib/arel/algebra/extensions/hash.rb b/lib/arel/algebra/extensions/hash.rb new file mode 100644 index 0000000000..7472b5aa73 --- /dev/null +++ b/lib/arel/algebra/extensions/hash.rb @@ -0,0 +1,7 @@ +class Hash + def bind(relation) + inject({}) do |bound, (key, value)| + bound.merge(key.bind(relation) => value.bind(relation)) + end + end +end \ No newline at end of file diff --git a/lib/arel/algebra/extensions/object.rb b/lib/arel/algebra/extensions/object.rb new file mode 100644 index 0000000000..d626407dcb --- /dev/null +++ b/lib/arel/algebra/extensions/object.rb @@ -0,0 +1,15 @@ +class Object + def bind(relation) + Arel::Value.new(self, relation) + end + + def find_correlate_in(relation) + bind(relation) + end + + def metaclass + class << self + self + end + end +end diff --git a/lib/arel/algebra/extensions/pathname.rb b/lib/arel/algebra/extensions/pathname.rb new file mode 100644 index 0000000000..2f7e2733e7 --- /dev/null +++ b/lib/arel/algebra/extensions/pathname.rb @@ -0,0 +1,5 @@ +class Pathname + def /(path) + (self + path).expand_path + end +end \ No newline at end of file diff --git a/lib/arel/algebra/predicates.rb b/lib/arel/algebra/predicates.rb new file mode 100644 index 0000000000..f83101306e --- /dev/null +++ b/lib/arel/algebra/predicates.rb @@ -0,0 +1,45 @@ +module Arel + class Predicate + end + + class Binary < Predicate + attributes :operand1, :operand2 + deriving :initialize + + def ==(other) + self.class === other and + @operand1 == other.operand1 and + @operand2 == other.operand2 + end + + def bind(relation) + self.class.new(operand1.find_correlate_in(relation), operand2.find_correlate_in(relation)) + end + end + + class Equality < Binary + def ==(other) + Equality === other and + ((operand1 == other.operand1 and operand2 == other.operand2) or + (operand1 == other.operand2 and operand2 == other.operand1)) + end + end + + class GreaterThanOrEqualTo < Binary + end + + class GreaterThan < Binary + end + + class LessThanOrEqualTo < Binary + end + + class LessThan < Binary + end + + class Match < Binary + end + + class In < Binary + end +end \ No newline at end of file diff --git a/lib/arel/algebra/primitives.rb b/lib/arel/algebra/primitives.rb new file mode 100644 index 0000000000..a4c3169e0b --- /dev/null +++ b/lib/arel/algebra/primitives.rb @@ -0,0 +1,4 @@ +require 'arel/algebra/primitives/attribute' +require 'arel/algebra/primitives/value' +require 'arel/algebra/primitives/expression' + diff --git a/lib/arel/algebra/primitives/attribute.rb b/lib/arel/algebra/primitives/attribute.rb new file mode 100644 index 0000000000..5e216770e4 --- /dev/null +++ b/lib/arel/algebra/primitives/attribute.rb @@ -0,0 +1,133 @@ +require 'set' + +module Arel + class Attribute + attributes :relation, :name, :alias, :ancestor + deriving :== + delegate :engine, :christener, :to => :relation + + def initialize(relation, name, options = {}) + @relation, @name, @alias, @ancestor = relation, name, options[:alias], options[:ancestor] + end + + def named?(hypothetical_name) + (@alias || name).to_s == hypothetical_name.to_s + end + + def aggregation? + false + end + + module Transformations + def self.included(klass) + klass.send :alias_method, :eql?, :== + end + + def hash + @hash ||= history.size + name.hash + relation.hash + end + + def as(aliaz = nil) + Attribute.new(relation, name, :alias => aliaz, :ancestor => self) + end + + def bind(new_relation) + relation == new_relation ? self : Attribute.new(new_relation, name, :alias => @alias, :ancestor => self) + end + + def to_attribute + self + end + end + include Transformations + + module Congruence + def history + @history ||= [self] + (ancestor ? ancestor.history : []) + end + + def join? + relation.join? + end + + def root + history.last + end + + def original_relation + @original_relation ||= original_attribute.relation + end + + def original_attribute + @original_attribute ||= history.detect { |a| !a.join? } + end + + def find_correlate_in(relation) + relation[self] || self + end + + def descends_from?(other) + history.include?(other) + end + + def /(other) + other ? (history & other.history).size : 0 + end + end + include Congruence + + module Predications + def eq(other) + Equality.new(self, other) + end + + def lt(other) + LessThan.new(self, other) + end + + def lteq(other) + LessThanOrEqualTo.new(self, other) + end + + def gt(other) + GreaterThan.new(self, other) + end + + def gteq(other) + GreaterThanOrEqualTo.new(self, other) + end + + def matches(regexp) + Match.new(self, regexp) + end + + def in(array) + In.new(self, array) + end + end + include Predications + + module Expressions + def count(distinct = false) + distinct ? Expression.new(self, "DISTINCT").count : Expression.new(self, "COUNT") + end + + def sum + Expression.new(self, "SUM") + end + + def maximum + Expression.new(self, "MAX") + end + + def minimum + Expression.new(self, "MIN") + end + + def average + Expression.new(self, "AVG") + end + end + include Expressions + end +end diff --git a/lib/arel/algebra/primitives/expression.rb b/lib/arel/algebra/primitives/expression.rb new file mode 100644 index 0000000000..b67a5e1f8e --- /dev/null +++ b/lib/arel/algebra/primitives/expression.rb @@ -0,0 +1,31 @@ +module Arel + class Expression < Attribute + attributes :attribute, :function_sql, :alias, :ancestor + deriving :== + delegate :relation, :to => :attribute + alias_method :name, :alias + + def initialize(attribute, function_sql, aliaz = nil, ancestor = nil) + @attribute, @function_sql, @alias, @ancestor = attribute, function_sql, aliaz, ancestor + end + + def aggregation? + true + end + + module Transformations + def as(aliaz) + Expression.new(attribute, function_sql, aliaz, self) + end + + def bind(new_relation) + new_relation == relation ? self : Expression.new(attribute.bind(new_relation), function_sql, @alias, self) + end + + def to_attribute + Attribute.new(relation, @alias, :ancestor => self) + end + end + include Transformations + end +end diff --git a/lib/arel/algebra/primitives/value.rb b/lib/arel/algebra/primitives/value.rb new file mode 100644 index 0000000000..91c4045507 --- /dev/null +++ b/lib/arel/algebra/primitives/value.rb @@ -0,0 +1,19 @@ +module Arel + class Value + attributes :value, :relation + deriving :initialize, :== + delegate :inclusion_predicate_sql, :equality_predicate_sql, :to => :value + + def bind(relation) + Value.new(value, relation) + end + + def aggregation? + false + end + + def to_attribute + value + end + end +end diff --git a/lib/arel/algebra/relations.rb b/lib/arel/algebra/relations.rb new file mode 100644 index 0000000000..03f04d2459 --- /dev/null +++ b/lib/arel/algebra/relations.rb @@ -0,0 +1,15 @@ +require 'arel/algebra/relations/relation' +require 'arel/algebra/relations/utilities/compound' +require 'arel/algebra/relations/utilities/nil' +require 'arel/algebra/relations/utilities/externalization' +require 'arel/algebra/relations/writes/delete' +require 'arel/algebra/relations/writes/update' +require 'arel/algebra/relations/writes/insert' +require 'arel/algebra/relations/operations/alias' +require 'arel/algebra/relations/operations/group' +require 'arel/algebra/relations/operations/join' +require 'arel/algebra/relations/operations/order' +require 'arel/algebra/relations/operations/project' +require 'arel/algebra/relations/operations/where' +require 'arel/algebra/relations/operations/skip' +require 'arel/algebra/relations/operations/take' \ No newline at end of file diff --git a/lib/arel/algebra/relations/operations/alias.rb b/lib/arel/algebra/relations/operations/alias.rb new file mode 100644 index 0000000000..67837f6a75 --- /dev/null +++ b/lib/arel/algebra/relations/operations/alias.rb @@ -0,0 +1,7 @@ +module Arel + class Alias < Compound + attributes :relation + deriving :initialize + alias_method :==, :equal? + end +end \ No newline at end of file diff --git a/lib/arel/algebra/relations/operations/group.rb b/lib/arel/algebra/relations/operations/group.rb new file mode 100644 index 0000000000..04fd9fea62 --- /dev/null +++ b/lib/arel/algebra/relations/operations/group.rb @@ -0,0 +1,15 @@ +module Arel + class Group < Compound + attributes :relation, :groupings + deriving :== + + def initialize(relation, *groupings, &block) + @relation = relation + @groupings = (groupings + (block_given?? [yield(relatoin)] : [])).collect { |g| g.bind(relation) } + end + + def externalizable? + true + end + end +end \ No newline at end of file diff --git a/lib/arel/algebra/relations/operations/join.rb b/lib/arel/algebra/relations/operations/join.rb new file mode 100644 index 0000000000..8e19254378 --- /dev/null +++ b/lib/arel/algebra/relations/operations/join.rb @@ -0,0 +1,41 @@ +module Arel + class Join < Relation + attributes :join_sql, :relation1, :relation2, :predicates + deriving :== + delegate :engine, :name, :to => :relation1 + hash_on :relation1 + + def initialize(join_sql, relation1, relation2 = Nil.instance, *predicates) + @join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates + end + + def attributes + @attributes ||= (relation1.externalize.attributes + + relation2.externalize.attributes).collect { |a| a.bind(self) } + end + + def wheres + # TESTME bind to self? + relation1.externalize.wheres + end + + def ons + @ons ||= @predicates.collect { |p| p.bind(self) } + end + + # TESTME + def externalizable? + relation1.externalizable? or relation2.externalizable? + end + + def join? + true + end + end + + class Relation + def join? + false + end + end +end diff --git a/lib/arel/algebra/relations/operations/order.rb b/lib/arel/algebra/relations/operations/order.rb new file mode 100644 index 0000000000..05af3fde4d --- /dev/null +++ b/lib/arel/algebra/relations/operations/order.rb @@ -0,0 +1,16 @@ +module Arel + class Order < Compound + attributes :relation, :orderings + deriving :== + + def initialize(relation, *orderings, &block) + @relation = relation + @orderings = (orderings + (block_given?? [yield(relation)] : [])).collect { |o| o.bind(relation) } + end + + # TESTME + def orders + (orderings + relation.orders).collect { |o| o.bind(self) } + end + end +end \ No newline at end of file diff --git a/lib/arel/algebra/relations/operations/project.rb b/lib/arel/algebra/relations/operations/project.rb new file mode 100644 index 0000000000..5507ea3163 --- /dev/null +++ b/lib/arel/algebra/relations/operations/project.rb @@ -0,0 +1,19 @@ +module Arel + class Project < Compound + attributes :relation, :projections + deriving :== + + def initialize(relation, *projections, &block) + @relation = relation + @projections = (projections + (block_given?? [yield(relation)] : [])).collect { |p| p.bind(relation) } + end + + def attributes + @attributes ||= projections.collect { |p| p.bind(self) } + end + + def externalizable? + attributes.any?(&:aggregation?) or relation.externalizable? + end + end +end diff --git a/lib/arel/algebra/relations/operations/skip.rb b/lib/arel/algebra/relations/operations/skip.rb new file mode 100644 index 0000000000..930e4c94ea --- /dev/null +++ b/lib/arel/algebra/relations/operations/skip.rb @@ -0,0 +1,10 @@ +module Arel + class Skip < Compound + attributes :relation, :skipped + deriving :initialize, :== + + def externalizable? + true + end + end +end \ No newline at end of file diff --git a/lib/arel/algebra/relations/operations/take.rb b/lib/arel/algebra/relations/operations/take.rb new file mode 100644 index 0000000000..2fd3fdf635 --- /dev/null +++ b/lib/arel/algebra/relations/operations/take.rb @@ -0,0 +1,10 @@ +module Arel + class Take < Compound + attributes :relation, :taken + deriving :initialize, :== + + def externalizable? + true + end + end +end \ No newline at end of file diff --git a/lib/arel/algebra/relations/operations/where.rb b/lib/arel/algebra/relations/operations/where.rb new file mode 100644 index 0000000000..608aaeb4b7 --- /dev/null +++ b/lib/arel/algebra/relations/operations/where.rb @@ -0,0 +1,16 @@ +module Arel + class Where < Compound + attributes :relation, :predicate + deriving :== + + def initialize(relation, *predicates, &block) + predicate = block_given?? yield(relation) : 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 + end +end diff --git a/lib/arel/algebra/relations/relation.rb b/lib/arel/algebra/relations/relation.rb new file mode 100644 index 0000000000..20badaf165 --- /dev/null +++ b/lib/arel/algebra/relations/relation.rb @@ -0,0 +1,134 @@ +module Arel + class Relation + attr_reader :count + + def session + Session.new + end + + def call + engine.read(self) + end + + def bind(relation) + self + end + + def root + self + end + + module Enumerable + include ::Enumerable + + def each(&block) + session.read(self).each(&block) + end + + def first + session.read(self).first + end + end + include Enumerable + + module Operable + def join(other_relation = nil, join_type = "INNER JOIN") + case other_relation + when String + Join.new(other_relation, self) + when Relation + JoinOperation.new(join_type, self, other_relation) + else + self + end + end + + def outer_join(other_relation = nil) + join(other_relation, "LEFT OUTER JOIN") + end + + [:where, :project, :order, :take, :skip, :group].each do |operation_name| + operation = <<-OPERATION + def #{operation_name}(*arguments, &block) + arguments.all?(&:blank?) && !block_given?? self : #{operation_name.to_s.classify}.new(self, *arguments, &block) + end + OPERATION + class_eval operation, __FILE__, __LINE__ + end + + def alias + Alias.new(self) + end + + module Writable + def insert(record) + session.create Insert.new(self, record); self + end + + def update(assignments) + session.update Update.new(self, assignments) + end + + def delete + session.delete Deletion.new(self) + end + end + include Writable + + JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do + def on(*predicates) + Join.new(join_sql, relation1, relation2, *predicates) + end + end + end + include Operable + + module AttributeAccessable + def [](index) + case index + when Symbol, String + find_attribute_matching_name(index) + when Attribute, Expression + find_attribute_matching_attribute(index) + when Array + index.collect { |i| self[i] } + end + end + + def find_attribute_matching_name(name) + attributes.detect { |a| a.named?(name) } + end + + def find_attribute_matching_attribute(attribute) + matching_attributes(attribute).max do |a1, a2| + (a1.original_attribute / attribute) <=> (a2.original_attribute / attribute) + end + end + + private + def matching_attributes(attribute) + (@matching_attributes ||= attributes.inject({}) do |hash, a| + (hash[a.root] ||= []) << a + hash + end)[attribute.root] || [] + end + + def has_attribute?(attribute) + !matching_attributes(attribute).empty? + end + end + include AttributeAccessable + + module DefaultOperations + def attributes; [] end + def wheres; [] end + def orders; [] end + def inserts; [] end + def groupings; [] end + def joins(formatter = nil); nil end # FIXME + def taken; nil end + def skipped; nil end + end + include DefaultOperations + end +end diff --git a/lib/arel/algebra/relations/utilities/compound.rb b/lib/arel/algebra/relations/utilities/compound.rb new file mode 100644 index 0000000000..e33b8dbf14 --- /dev/null +++ b/lib/arel/algebra/relations/utilities/compound.rb @@ -0,0 +1,18 @@ +module Arel + class Compound < Relation + attr_reader :relation + hash_on :relation + delegate :joins, :join?, :inserts, :taken, :skipped, :name, :externalizable?, + :column_for, :engine, :table, :table_sql, :array, + :to => :relation + + [:attributes, :wheres, :groupings, :orders].each do |operation_name| + operation = <<-OPERATION + def #{operation_name} + @#{operation_name} ||= relation.#{operation_name}.collect { |o| o.bind(self) } + end + OPERATION + class_eval operation, __FILE__, __LINE__ + end + end +end diff --git a/lib/arel/algebra/relations/utilities/externalization.rb b/lib/arel/algebra/relations/utilities/externalization.rb new file mode 100644 index 0000000000..bd067f2304 --- /dev/null +++ b/lib/arel/algebra/relations/utilities/externalization.rb @@ -0,0 +1,24 @@ +module Arel + class Externalization < Compound + attributes :relation + deriving :initialize, :== + + def wheres + [] + end + + def attributes + @attributes ||= relation.attributes.collect(&:to_attribute).collect { |a| a.bind(self) } + end + end + + class Relation + def externalize + @externalized ||= externalizable?? Externalization.new(self) : self + end + + def externalizable? + false + end + end +end diff --git a/lib/arel/algebra/relations/utilities/nil.rb b/lib/arel/algebra/relations/utilities/nil.rb new file mode 100644 index 0000000000..6a9d678c45 --- /dev/null +++ b/lib/arel/algebra/relations/utilities/nil.rb @@ -0,0 +1,7 @@ +require 'singleton' + +module Arel + class Nil < Relation + include Singleton + end +end diff --git a/lib/arel/algebra/relations/writes/delete.rb b/lib/arel/algebra/relations/writes/delete.rb new file mode 100644 index 0000000000..a94067c7fa --- /dev/null +++ b/lib/arel/algebra/relations/writes/delete.rb @@ -0,0 +1,10 @@ +module Arel + class Deletion < Compound + attributes :relation + deriving :initialize, :== + + def call + engine.delete(self) + end + end +end diff --git a/lib/arel/algebra/relations/writes/insert.rb b/lib/arel/algebra/relations/writes/insert.rb new file mode 100644 index 0000000000..6d85e9769a --- /dev/null +++ b/lib/arel/algebra/relations/writes/insert.rb @@ -0,0 +1,14 @@ +module Arel + class Insert < Compound + attributes :relation, :record + deriving :== + + def initialize(relation, record) + @relation, @record = relation, record.bind(relation) + end + + def call + engine.create(self) + end + end +end diff --git a/lib/arel/algebra/relations/writes/update.rb b/lib/arel/algebra/relations/writes/update.rb new file mode 100644 index 0000000000..e647218a80 --- /dev/null +++ b/lib/arel/algebra/relations/writes/update.rb @@ -0,0 +1,14 @@ +module Arel + class Update < Compound + attributes :relation, :assignments + deriving :== + + def initialize(relation, assignments) + @relation, @assignments = relation, assignments + end + + def call + engine.update(self) + end + end +end diff --git a/lib/arel/arel.rb b/lib/arel/arel.rb deleted file mode 100644 index 7780d45e25..0000000000 --- a/lib/arel/arel.rb +++ /dev/null @@ -1,3 +0,0 @@ -def Arel(name, engine = (Arel::Table.engine || ActiveRecord::Base.connection)) - Arel::Table.new(name, engine) -end diff --git a/lib/arel/engines.rb b/lib/arel/engines.rb index 63a929528f..3f854edf90 100644 --- a/lib/arel/engines.rb +++ b/lib/arel/engines.rb @@ -1,2 +1,2 @@ -require 'arel/engines/sql/sql' -require 'arel/engines/array/array' \ No newline at end of file +require 'arel/engines/sql' +require 'arel/engines/memory' \ No newline at end of file diff --git a/lib/arel/engines/array/array.rb b/lib/arel/engines/array/array.rb deleted file mode 100644 index 3a3a47308a..0000000000 --- a/lib/arel/engines/array/array.rb +++ /dev/null @@ -1 +0,0 @@ -require 'arel/engines/array/relations/array' \ No newline at end of file diff --git a/lib/arel/engines/array/relations/array.rb b/lib/arel/engines/array/relations/array.rb deleted file mode 100644 index dac65abbc2..0000000000 --- a/lib/arel/engines/array/relations/array.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Arel - class Array < Relation - include Recursion::BaseCase - - def initialize(array, attribute_names) - @array, @attribute_names = array, attribute_names - end - - def attributes - @attributes ||= @attribute_names.collect do |name| - Attribute.new(self, name.to_sym) - end - end - - def call(connection = nil) - @array.collect { |row| attributes.zip(row).to_hash } - end - end -end \ No newline at end of file diff --git a/lib/arel/engines/memory.rb b/lib/arel/engines/memory.rb new file mode 100644 index 0000000000..df6f6f3d48 --- /dev/null +++ b/lib/arel/engines/memory.rb @@ -0,0 +1,4 @@ +require 'arel/engines/memory/relations' +require 'arel/engines/memory/primitives' +require 'arel/engines/memory/engine' +require 'arel/engines/memory/predicates' \ No newline at end of file diff --git a/lib/arel/engines/memory/engine.rb b/lib/arel/engines/memory/engine.rb new file mode 100644 index 0000000000..67a084f2cd --- /dev/null +++ b/lib/arel/engines/memory/engine.rb @@ -0,0 +1,12 @@ +module Arel + module Memory + class Engine + module CRUD + def read(relation) + relation.eval + end + end + include CRUD + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/memory/predicates.rb b/lib/arel/engines/memory/predicates.rb new file mode 100644 index 0000000000..3522ea3ffa --- /dev/null +++ b/lib/arel/engines/memory/predicates.rb @@ -0,0 +1,58 @@ +module Arel + class Predicate + def or(other_predicate) + Or.new(self, other_predicate) + end + + def and(other_predicate) + And.new(self, other_predicate) + end + end + + class Binary < Predicate + def eval(row) + operand1.eval(row).send(operator, operand2.eval(row)) + end + end + + class CompoundPredicate < Binary + def to_sql(formatter = nil) + "(#{operand1.to_sql(formatter)} #{predicate_sql} #{operand2.to_sql(formatter)})" + end + end + + class Or < CompoundPredicate + def predicate_sql; "OR" end + end + + class And < CompoundPredicate + def predicate_sql; "AND" end + end + + class Equality < Binary + def ==(other) + Equality === other and + ((operand1 == other.operand1 and operand2 == other.operand2) or + (operand1 == other.operand2 and operand2 == other.operand1)) + end + end + + class GreaterThanOrEqualTo < Binary + end + + class GreaterThan < Binary + end + + class LessThanOrEqualTo < Binary + end + + class LessThan < Binary + def operator; :< end + end + + class Match < Binary + end + + class In < Binary + end +end diff --git a/lib/arel/engines/memory/primitives.rb b/lib/arel/engines/memory/primitives.rb new file mode 100644 index 0000000000..4d5c76e956 --- /dev/null +++ b/lib/arel/engines/memory/primitives.rb @@ -0,0 +1,2 @@ +require 'arel/engines/memory/primitives/attribute' +require 'arel/engines/memory/primitives/value' diff --git a/lib/arel/engines/memory/primitives/attribute.rb b/lib/arel/engines/memory/primitives/attribute.rb new file mode 100644 index 0000000000..9864feadc2 --- /dev/null +++ b/lib/arel/engines/memory/primitives/attribute.rb @@ -0,0 +1,7 @@ +module Arel + class Attribute + def eval(row) + row[self] + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/memory/primitives/value.rb b/lib/arel/engines/memory/primitives/value.rb new file mode 100644 index 0000000000..b83cd02e57 --- /dev/null +++ b/lib/arel/engines/memory/primitives/value.rb @@ -0,0 +1,7 @@ +module Arel + class Value + def eval(row) + value + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/memory/relations.rb b/lib/arel/engines/memory/relations.rb new file mode 100644 index 0000000000..6361d7c9d7 --- /dev/null +++ b/lib/arel/engines/memory/relations.rb @@ -0,0 +1,2 @@ +require 'arel/engines/memory/relations/array' +require 'arel/engines/memory/relations/operations/where' diff --git a/lib/arel/engines/memory/relations/array.rb b/lib/arel/engines/memory/relations/array.rb new file mode 100644 index 0000000000..c02c62891b --- /dev/null +++ b/lib/arel/engines/memory/relations/array.rb @@ -0,0 +1,21 @@ +module Arel + class Array < Relation + attributes :array, :attribute_names + deriving :initialize + include Recursion::BaseCase + + def engine + @engine ||= Memory::Engine.new + end + + def attributes + @attributes ||= @attribute_names.collect do |name| + Attribute.new(self, name.to_sym) + end + end + + def eval + @array.collect { |row| attributes.zip(row).to_hash } + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/memory/relations/operations/where.rb b/lib/arel/engines/memory/relations/operations/where.rb new file mode 100644 index 0000000000..eb11fb55fd --- /dev/null +++ b/lib/arel/engines/memory/relations/operations/where.rb @@ -0,0 +1,7 @@ +module Arel + class Where < Compound + def eval + relation.eval.select { |row| predicate.eval(row) } + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql.rb b/lib/arel/engines/sql.rb new file mode 100644 index 0000000000..aed1fd861e --- /dev/null +++ b/lib/arel/engines/sql.rb @@ -0,0 +1,7 @@ +require 'arel/engines/sql/engine' +require 'arel/engines/sql/relations' +require 'arel/engines/sql/primitives' +require 'arel/engines/sql/predicates' +require 'arel/engines/sql/formatters' +require 'arel/engines/sql/extensions' +require 'arel/engines/sql/christener' \ No newline at end of file diff --git a/lib/arel/engines/sql/primitives/attribute.rb b/lib/arel/engines/sql/primitives/attribute.rb index 48de690b6f..ad78a9ec5b 100644 --- a/lib/arel/engines/sql/primitives/attribute.rb +++ b/lib/arel/engines/sql/primitives/attribute.rb @@ -1,5 +1,3 @@ -require 'set' - module Arel class Attribute def column diff --git a/lib/arel/engines/sql/relations.rb b/lib/arel/engines/sql/relations.rb index 4de01b2691..39ef8852a1 100644 --- a/lib/arel/engines/sql/relations.rb +++ b/lib/arel/engines/sql/relations.rb @@ -1,5 +1,10 @@ -require 'arel/engines/sql/relations/utilities' +require 'arel/engines/sql/relations/utilities/recursion' +require 'arel/engines/sql/relations/utilities/externalization' +require 'arel/engines/sql/relations/utilities/nil' require 'arel/engines/sql/relations/relation' -require 'arel/engines/sql/relations/operations' -require 'arel/engines/sql/relations/writes' -require 'arel/engines/sql/relations/table' \ No newline at end of file +require 'arel/engines/sql/relations/table' +require 'arel/engines/sql/relations/operations/join' +require 'arel/engines/sql/relations/operations/alias' +require 'arel/engines/sql/relations/writes/delete' +require 'arel/engines/sql/relations/writes/insert' +require 'arel/engines/sql/relations/writes/update' \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/operations.rb b/lib/arel/engines/sql/relations/operations.rb deleted file mode 100644 index ff33fc6bc3..0000000000 --- a/lib/arel/engines/sql/relations/operations.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'arel/engines/sql/relations/operations/alias' -require 'arel/engines/sql/relations/operations/join' diff --git a/lib/arel/engines/sql/relations/table.rb b/lib/arel/engines/sql/relations/table.rb index 0433abbbb2..2653744149 100644 --- a/lib/arel/engines/sql/relations/table.rb +++ b/lib/arel/engines/sql/relations/table.rb @@ -34,3 +34,8 @@ module Arel end end end + +def Table(name, engine = Arel::Table.engine) + Arel::Table.new(name, engine) +end + diff --git a/lib/arel/engines/sql/relations/utilities.rb b/lib/arel/engines/sql/relations/utilities.rb deleted file mode 100644 index a1451ed448..0000000000 --- a/lib/arel/engines/sql/relations/utilities.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'arel/engines/sql/relations/utilities/recursion' -require 'arel/engines/sql/relations/utilities/externalization' -require 'arel/engines/sql/relations/utilities/nil' diff --git a/lib/arel/engines/sql/relations/writes.rb b/lib/arel/engines/sql/relations/writes.rb deleted file mode 100644 index dcadc326d9..0000000000 --- a/lib/arel/engines/sql/relations/writes.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'arel/engines/sql/relations/writes/delete' -require 'arel/engines/sql/relations/writes/insert' -require 'arel/engines/sql/relations/writes/update' diff --git a/lib/arel/engines/sql/sql.rb b/lib/arel/engines/sql/sql.rb deleted file mode 100644 index aed1fd861e..0000000000 --- a/lib/arel/engines/sql/sql.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'arel/engines/sql/engine' -require 'arel/engines/sql/relations' -require 'arel/engines/sql/primitives' -require 'arel/engines/sql/predicates' -require 'arel/engines/sql/formatters' -require 'arel/engines/sql/extensions' -require 'arel/engines/sql/christener' \ No newline at end of file diff --git a/lib/arel/extensions.rb b/lib/arel/extensions.rb deleted file mode 100644 index 299ba0631c..0000000000 --- a/lib/arel/extensions.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'arel/extensions/object' -require 'arel/extensions/class' -require 'arel/extensions/array' -require 'arel/extensions/hash' diff --git a/lib/arel/extensions/array.rb b/lib/arel/extensions/array.rb deleted file mode 100644 index 5b6d6d6abd..0000000000 --- a/lib/arel/extensions/array.rb +++ /dev/null @@ -1,5 +0,0 @@ -class Array - def to_hash - Hash[*flatten] - end -end \ No newline at end of file diff --git a/lib/arel/extensions/class.rb b/lib/arel/extensions/class.rb deleted file mode 100644 index f37898e7d7..0000000000 --- a/lib/arel/extensions/class.rb +++ /dev/null @@ -1,37 +0,0 @@ -class Class - def attributes(*attrs) - @attributes = attrs - attr_reader *attrs - end - - def deriving(*methods) - methods.each { |m| derive m } - end - - def derive(method_name) - methods = { - :initialize => " - def #{method_name}(#{@attributes.join(',')}) - #{@attributes.collect { |a| "@#{a} = #{a}" }.join("\n")} - end - ", - :== => " - def ==(other) - #{name} === other && - #{@attributes.collect { |a| "@#{a} == other.#{a}" }.join(" &&\n")} - end - " - } - class_eval methods[method_name], __FILE__, __LINE__ - end - - def hash_on(delegatee) - define_method :eql? do |other| - self == other - end - - define_method :hash do - @hash ||= delegatee.hash - end - end -end \ No newline at end of file diff --git a/lib/arel/extensions/hash.rb b/lib/arel/extensions/hash.rb deleted file mode 100644 index 7472b5aa73..0000000000 --- a/lib/arel/extensions/hash.rb +++ /dev/null @@ -1,7 +0,0 @@ -class Hash - def bind(relation) - inject({}) do |bound, (key, value)| - bound.merge(key.bind(relation) => value.bind(relation)) - end - end -end \ No newline at end of file diff --git a/lib/arel/extensions/object.rb b/lib/arel/extensions/object.rb deleted file mode 100644 index d626407dcb..0000000000 --- a/lib/arel/extensions/object.rb +++ /dev/null @@ -1,15 +0,0 @@ -class Object - def bind(relation) - Arel::Value.new(self, relation) - end - - def find_correlate_in(relation) - bind(relation) - end - - def metaclass - class << self - self - end - end -end diff --git a/lib/arel/predicates.rb b/lib/arel/predicates.rb deleted file mode 100644 index aa206d4e96..0000000000 --- a/lib/arel/predicates.rb +++ /dev/null @@ -1,66 +0,0 @@ -module Arel - class Predicate - def or(other_predicate) - Or.new(self, other_predicate) - end - - def and(other_predicate) - And.new(self, other_predicate) - end - end - - class Binary < Predicate - attributes :operand1, :operand2 - deriving :initialize - - def ==(other) - self.class === other and - @operand1 == other.operand1 and - @operand2 == other.operand2 - end - - def bind(relation) - self.class.new(operand1.find_correlate_in(relation), operand2.find_correlate_in(relation)) - end - end - - class CompoundPredicate < Binary - def to_sql(formatter = nil) - "(#{operand1.to_sql(formatter)} #{predicate_sql} #{operand2.to_sql(formatter)})" - end - end - - class Or < CompoundPredicate - def predicate_sql; "OR" end - end - - class And < CompoundPredicate - def predicate_sql; "AND" end - end - - class Equality < Binary - def ==(other) - Equality === other and - ((operand1 == other.operand1 and operand2 == other.operand2) or - (operand1 == other.operand2 and operand2 == other.operand1)) - end - end - - class GreaterThanOrEqualTo < Binary - end - - class GreaterThan < Binary - end - - class LessThanOrEqualTo < Binary - end - - class LessThan < Binary - end - - class Match < Binary - end - - class In < Binary - end -end diff --git a/lib/arel/primitives.rb b/lib/arel/primitives.rb deleted file mode 100644 index d84713d3d5..0000000000 --- a/lib/arel/primitives.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'arel/primitives/attribute' -require 'arel/primitives/value' -require 'arel/primitives/expression' - diff --git a/lib/arel/primitives/attribute.rb b/lib/arel/primitives/attribute.rb deleted file mode 100644 index 5e216770e4..0000000000 --- a/lib/arel/primitives/attribute.rb +++ /dev/null @@ -1,133 +0,0 @@ -require 'set' - -module Arel - class Attribute - attributes :relation, :name, :alias, :ancestor - deriving :== - delegate :engine, :christener, :to => :relation - - def initialize(relation, name, options = {}) - @relation, @name, @alias, @ancestor = relation, name, options[:alias], options[:ancestor] - end - - def named?(hypothetical_name) - (@alias || name).to_s == hypothetical_name.to_s - end - - def aggregation? - false - end - - module Transformations - def self.included(klass) - klass.send :alias_method, :eql?, :== - end - - def hash - @hash ||= history.size + name.hash + relation.hash - end - - def as(aliaz = nil) - Attribute.new(relation, name, :alias => aliaz, :ancestor => self) - end - - def bind(new_relation) - relation == new_relation ? self : Attribute.new(new_relation, name, :alias => @alias, :ancestor => self) - end - - def to_attribute - self - end - end - include Transformations - - module Congruence - def history - @history ||= [self] + (ancestor ? ancestor.history : []) - end - - def join? - relation.join? - end - - def root - history.last - end - - def original_relation - @original_relation ||= original_attribute.relation - end - - def original_attribute - @original_attribute ||= history.detect { |a| !a.join? } - end - - def find_correlate_in(relation) - relation[self] || self - end - - def descends_from?(other) - history.include?(other) - end - - def /(other) - other ? (history & other.history).size : 0 - end - end - include Congruence - - module Predications - def eq(other) - Equality.new(self, other) - end - - def lt(other) - LessThan.new(self, other) - end - - def lteq(other) - LessThanOrEqualTo.new(self, other) - end - - def gt(other) - GreaterThan.new(self, other) - end - - def gteq(other) - GreaterThanOrEqualTo.new(self, other) - end - - def matches(regexp) - Match.new(self, regexp) - end - - def in(array) - In.new(self, array) - end - end - include Predications - - module Expressions - def count(distinct = false) - distinct ? Expression.new(self, "DISTINCT").count : Expression.new(self, "COUNT") - end - - def sum - Expression.new(self, "SUM") - end - - def maximum - Expression.new(self, "MAX") - end - - def minimum - Expression.new(self, "MIN") - end - - def average - Expression.new(self, "AVG") - end - end - include Expressions - end -end diff --git a/lib/arel/primitives/expression.rb b/lib/arel/primitives/expression.rb deleted file mode 100644 index b67a5e1f8e..0000000000 --- a/lib/arel/primitives/expression.rb +++ /dev/null @@ -1,31 +0,0 @@ -module Arel - class Expression < Attribute - attributes :attribute, :function_sql, :alias, :ancestor - deriving :== - delegate :relation, :to => :attribute - alias_method :name, :alias - - def initialize(attribute, function_sql, aliaz = nil, ancestor = nil) - @attribute, @function_sql, @alias, @ancestor = attribute, function_sql, aliaz, ancestor - end - - def aggregation? - true - end - - module Transformations - def as(aliaz) - Expression.new(attribute, function_sql, aliaz, self) - end - - def bind(new_relation) - new_relation == relation ? self : Expression.new(attribute.bind(new_relation), function_sql, @alias, self) - end - - def to_attribute - Attribute.new(relation, @alias, :ancestor => self) - end - end - include Transformations - end -end diff --git a/lib/arel/primitives/value.rb b/lib/arel/primitives/value.rb deleted file mode 100644 index 91c4045507..0000000000 --- a/lib/arel/primitives/value.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Arel - class Value - attributes :value, :relation - deriving :initialize, :== - delegate :inclusion_predicate_sql, :equality_predicate_sql, :to => :value - - def bind(relation) - Value.new(value, relation) - end - - def aggregation? - false - end - - def to_attribute - value - end - end -end diff --git a/lib/arel/relations.rb b/lib/arel/relations.rb deleted file mode 100644 index f97c35e56e..0000000000 --- a/lib/arel/relations.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'arel/relations/relation' -require 'arel/relations/utilities' -require 'arel/relations/writes' -require 'arel/relations/operations' \ No newline at end of file diff --git a/lib/arel/relations/operations.rb b/lib/arel/relations/operations.rb deleted file mode 100644 index c598c7fcc9..0000000000 --- a/lib/arel/relations/operations.rb +++ /dev/null @@ -1,8 +0,0 @@ -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 deleted file mode 100644 index 67837f6a75..0000000000 --- a/lib/arel/relations/operations/alias.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Arel - class Alias < Compound - attributes :relation - deriving :initialize - alias_method :==, :equal? - end -end \ No newline at end of file diff --git a/lib/arel/relations/operations/group.rb b/lib/arel/relations/operations/group.rb deleted file mode 100644 index 04fd9fea62..0000000000 --- a/lib/arel/relations/operations/group.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Arel - class Group < Compound - attributes :relation, :groupings - deriving :== - - def initialize(relation, *groupings, &block) - @relation = relation - @groupings = (groupings + (block_given?? [yield(relatoin)] : [])).collect { |g| g.bind(relation) } - end - - def externalizable? - 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 deleted file mode 100644 index 8e19254378..0000000000 --- a/lib/arel/relations/operations/join.rb +++ /dev/null @@ -1,41 +0,0 @@ -module Arel - class Join < Relation - attributes :join_sql, :relation1, :relation2, :predicates - deriving :== - delegate :engine, :name, :to => :relation1 - hash_on :relation1 - - def initialize(join_sql, relation1, relation2 = Nil.instance, *predicates) - @join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates - end - - def attributes - @attributes ||= (relation1.externalize.attributes + - relation2.externalize.attributes).collect { |a| a.bind(self) } - end - - def wheres - # TESTME bind to self? - relation1.externalize.wheres - end - - def ons - @ons ||= @predicates.collect { |p| p.bind(self) } - end - - # TESTME - def externalizable? - relation1.externalizable? or relation2.externalizable? - end - - def join? - true - end - end - - class Relation - def join? - false - end - end -end diff --git a/lib/arel/relations/operations/order.rb b/lib/arel/relations/operations/order.rb deleted file mode 100644 index 05af3fde4d..0000000000 --- a/lib/arel/relations/operations/order.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Arel - class Order < Compound - attributes :relation, :orderings - deriving :== - - def initialize(relation, *orderings, &block) - @relation = relation - @orderings = (orderings + (block_given?? [yield(relation)] : [])).collect { |o| o.bind(relation) } - end - - # TESTME - def orders - (orderings + relation.orders).collect { |o| o.bind(self) } - 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 deleted file mode 100644 index 5507ea3163..0000000000 --- a/lib/arel/relations/operations/project.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Arel - class Project < Compound - attributes :relation, :projections - deriving :== - - def initialize(relation, *projections, &block) - @relation = relation - @projections = (projections + (block_given?? [yield(relation)] : [])).collect { |p| p.bind(relation) } - end - - def attributes - @attributes ||= projections.collect { |p| p.bind(self) } - end - - def externalizable? - attributes.any?(&:aggregation?) or relation.externalizable? - end - end -end diff --git a/lib/arel/relations/operations/skip.rb b/lib/arel/relations/operations/skip.rb deleted file mode 100644 index 930e4c94ea..0000000000 --- a/lib/arel/relations/operations/skip.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Arel - class Skip < Compound - attributes :relation, :skipped - deriving :initialize, :== - - def externalizable? - true - 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 deleted file mode 100644 index 2fd3fdf635..0000000000 --- a/lib/arel/relations/operations/take.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Arel - class Take < Compound - attributes :relation, :taken - deriving :initialize, :== - - def externalizable? - true - 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 deleted file mode 100644 index 608aaeb4b7..0000000000 --- a/lib/arel/relations/operations/where.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Arel - class Where < Compound - attributes :relation, :predicate - deriving :== - - def initialize(relation, *predicates, &block) - predicate = block_given?? yield(relation) : 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 - end -end diff --git a/lib/arel/relations/relation.rb b/lib/arel/relations/relation.rb deleted file mode 100644 index 20badaf165..0000000000 --- a/lib/arel/relations/relation.rb +++ /dev/null @@ -1,134 +0,0 @@ -module Arel - class Relation - attr_reader :count - - def session - Session.new - end - - def call - engine.read(self) - end - - def bind(relation) - self - end - - def root - self - end - - module Enumerable - include ::Enumerable - - def each(&block) - session.read(self).each(&block) - end - - def first - session.read(self).first - end - end - include Enumerable - - module Operable - def join(other_relation = nil, join_type = "INNER JOIN") - case other_relation - when String - Join.new(other_relation, self) - when Relation - JoinOperation.new(join_type, self, other_relation) - else - self - end - end - - def outer_join(other_relation = nil) - join(other_relation, "LEFT OUTER JOIN") - end - - [:where, :project, :order, :take, :skip, :group].each do |operation_name| - operation = <<-OPERATION - def #{operation_name}(*arguments, &block) - arguments.all?(&:blank?) && !block_given?? self : #{operation_name.to_s.classify}.new(self, *arguments, &block) - end - OPERATION - class_eval operation, __FILE__, __LINE__ - end - - def alias - Alias.new(self) - end - - module Writable - def insert(record) - session.create Insert.new(self, record); self - end - - def update(assignments) - session.update Update.new(self, assignments) - end - - def delete - session.delete Deletion.new(self) - end - end - include Writable - - JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do - def on(*predicates) - Join.new(join_sql, relation1, relation2, *predicates) - end - end - end - include Operable - - module AttributeAccessable - def [](index) - case index - when Symbol, String - find_attribute_matching_name(index) - when Attribute, Expression - find_attribute_matching_attribute(index) - when Array - index.collect { |i| self[i] } - end - end - - def find_attribute_matching_name(name) - attributes.detect { |a| a.named?(name) } - end - - def find_attribute_matching_attribute(attribute) - matching_attributes(attribute).max do |a1, a2| - (a1.original_attribute / attribute) <=> (a2.original_attribute / attribute) - end - end - - private - def matching_attributes(attribute) - (@matching_attributes ||= attributes.inject({}) do |hash, a| - (hash[a.root] ||= []) << a - hash - end)[attribute.root] || [] - end - - def has_attribute?(attribute) - !matching_attributes(attribute).empty? - end - end - include AttributeAccessable - - module DefaultOperations - def attributes; [] end - def wheres; [] end - def orders; [] end - def inserts; [] end - def groupings; [] end - def joins(formatter = nil); nil end # FIXME - def taken; nil end - def skipped; nil end - end - include DefaultOperations - end -end diff --git a/lib/arel/relations/utilities.rb b/lib/arel/relations/utilities.rb deleted file mode 100644 index fbd949ef0c..0000000000 --- a/lib/arel/relations/utilities.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'arel/relations/utilities/compound' -require 'arel/relations/utilities/nil' -require 'arel/relations/utilities/externalization' diff --git a/lib/arel/relations/utilities/compound.rb b/lib/arel/relations/utilities/compound.rb deleted file mode 100644 index b1e8054d4d..0000000000 --- a/lib/arel/relations/utilities/compound.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Arel - class Compound < Relation - attr_reader :relation - hash_on :relation - delegate :joins, :join?, :inserts, :taken, :skipped, :name, :externalizable?, - :column_for, :engine, :table, :table_sql, - :to => :relation - - [:attributes, :wheres, :groupings, :orders].each do |operation_name| - operation = <<-OPERATION - def #{operation_name} - @#{operation_name} ||= relation.#{operation_name}.collect { |o| o.bind(self) } - end - OPERATION - class_eval operation, __FILE__, __LINE__ - end - end -end diff --git a/lib/arel/relations/utilities/externalization.rb b/lib/arel/relations/utilities/externalization.rb deleted file mode 100644 index bd067f2304..0000000000 --- a/lib/arel/relations/utilities/externalization.rb +++ /dev/null @@ -1,24 +0,0 @@ -module Arel - class Externalization < Compound - attributes :relation - deriving :initialize, :== - - def wheres - [] - end - - def attributes - @attributes ||= relation.attributes.collect(&:to_attribute).collect { |a| a.bind(self) } - end - end - - class Relation - def externalize - @externalized ||= externalizable?? Externalization.new(self) : self - end - - def externalizable? - false - end - end -end diff --git a/lib/arel/relations/utilities/nil.rb b/lib/arel/relations/utilities/nil.rb deleted file mode 100644 index 6a9d678c45..0000000000 --- a/lib/arel/relations/utilities/nil.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'singleton' - -module Arel - class Nil < Relation - include Singleton - end -end diff --git a/lib/arel/relations/writes.rb b/lib/arel/relations/writes.rb deleted file mode 100644 index 1495d9c857..0000000000 --- a/lib/arel/relations/writes.rb +++ /dev/null @@ -1,3 +0,0 @@ -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 deleted file mode 100644 index a94067c7fa..0000000000 --- a/lib/arel/relations/writes/delete.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Arel - class Deletion < Compound - attributes :relation - deriving :initialize, :== - - def call - engine.delete(self) - end - end -end diff --git a/lib/arel/relations/writes/insert.rb b/lib/arel/relations/writes/insert.rb deleted file mode 100644 index 6d85e9769a..0000000000 --- a/lib/arel/relations/writes/insert.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Arel - class Insert < Compound - attributes :relation, :record - deriving :== - - def initialize(relation, record) - @relation, @record = relation, record.bind(relation) - end - - def call - engine.create(self) - end - end -end diff --git a/lib/arel/relations/writes/update.rb b/lib/arel/relations/writes/update.rb deleted file mode 100644 index e647218a80..0000000000 --- a/lib/arel/relations/writes/update.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Arel - class Update < Compound - attributes :relation, :assignments - deriving :== - - def initialize(relation, assignments) - @relation, @assignments = relation, assignments - end - - def call - engine.update(self) - end - end -end diff --git a/lib/arel/session.rb b/lib/arel/session.rb index 9c2ddc535b..cf04e8a93a 100644 --- a/lib/arel/session.rb +++ b/lib/arel/session.rb @@ -1,5 +1,3 @@ -require 'singleton' - module Arel class Session class << self -- cgit v1.2.3 From b0a45d52fdb7d8ce564f4dc2013bc790f98f1da3 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 14:38:09 -0400 Subject: consolidated files Conflicts: lib/arel/algebra/predicates.rb lib/arel/algebra/relations/writes/delete.rb lib/arel/algebra/relations/writes/insert.rb lib/arel/algebra/relations/writes/update.rb lib/arel/engines/memory/predicates.rb lib/arel/engines/memory/relations.rb lib/arel/engines/sql/primitives/attribute.rb lib/arel/engines/sql/relations/writes/insert.rb lib/arel/engines/sql/relations/writes/update.rb --- lib/arel/algebra/predicates.rb | 30 ++++++++---------- lib/arel/algebra/relations.rb | 4 +-- lib/arel/algebra/relations/writes.rb | 36 ++++++++++++++++++++++ lib/arel/algebra/relations/writes/delete.rb | 10 ------ lib/arel/algebra/relations/writes/insert.rb | 14 --------- lib/arel/algebra/relations/writes/update.rb | 14 --------- lib/arel/engines/memory/predicates.rb | 14 --------- lib/arel/engines/memory/primitives.rb | 15 +++++++-- lib/arel/engines/memory/primitives/attribute.rb | 7 ----- lib/arel/engines/memory/primitives/value.rb | 7 ----- lib/arel/engines/memory/relations.rb | 3 +- lib/arel/engines/memory/relations/operations.rb | 7 +++++ .../engines/memory/relations/operations/where.rb | 7 ----- lib/arel/engines/sql/primitives.rb | 34 ++++++++++++++++++-- lib/arel/engines/sql/primitives/attribute.rb | 15 --------- lib/arel/engines/sql/primitives/expression.rb | 7 ----- lib/arel/engines/sql/primitives/value.rb | 11 ------- lib/arel/engines/sql/relations.rb | 4 +-- lib/arel/engines/sql/relations/writes.rb | 36 ++++++++++++++++++++++ lib/arel/engines/sql/relations/writes/delete.rb | 12 -------- lib/arel/engines/sql/relations/writes/insert.rb | 12 -------- lib/arel/engines/sql/relations/writes/update.rb | 14 --------- 22 files changed, 140 insertions(+), 173 deletions(-) create mode 100644 lib/arel/algebra/relations/writes.rb delete mode 100644 lib/arel/algebra/relations/writes/delete.rb delete mode 100644 lib/arel/algebra/relations/writes/insert.rb delete mode 100644 lib/arel/algebra/relations/writes/update.rb delete mode 100644 lib/arel/engines/memory/primitives/attribute.rb delete mode 100644 lib/arel/engines/memory/primitives/value.rb create mode 100644 lib/arel/engines/memory/relations/operations.rb delete mode 100644 lib/arel/engines/memory/relations/operations/where.rb delete mode 100644 lib/arel/engines/sql/primitives/attribute.rb delete mode 100644 lib/arel/engines/sql/primitives/expression.rb delete mode 100644 lib/arel/engines/sql/primitives/value.rb create mode 100644 lib/arel/engines/sql/relations/writes.rb delete mode 100644 lib/arel/engines/sql/relations/writes/delete.rb delete mode 100644 lib/arel/engines/sql/relations/writes/insert.rb delete mode 100644 lib/arel/engines/sql/relations/writes/update.rb (limited to 'lib') diff --git a/lib/arel/algebra/predicates.rb b/lib/arel/algebra/predicates.rb index f83101306e..7f093ded6d 100644 --- a/lib/arel/algebra/predicates.rb +++ b/lib/arel/algebra/predicates.rb @@ -1,5 +1,12 @@ module Arel class Predicate + def or(other_predicate) + Or.new(self, other_predicate) + end + + def and(other_predicate) + And.new(self, other_predicate) + end end class Binary < Predicate @@ -25,21 +32,10 @@ module Arel end end - class GreaterThanOrEqualTo < Binary - end - - class GreaterThan < Binary - end - - class LessThanOrEqualTo < Binary - end - - class LessThan < Binary - end - - class Match < Binary - end - - class In < Binary - end + class GreaterThanOrEqualTo < Binary; end + class GreaterThan < Binary; end + class LessThanOrEqualTo < Binary; end + class LessThan < Binary; end + class Match < Binary; end + class In < Binary; end end \ No newline at end of file diff --git a/lib/arel/algebra/relations.rb b/lib/arel/algebra/relations.rb index 03f04d2459..b75a31e5e3 100644 --- a/lib/arel/algebra/relations.rb +++ b/lib/arel/algebra/relations.rb @@ -2,9 +2,7 @@ require 'arel/algebra/relations/relation' require 'arel/algebra/relations/utilities/compound' require 'arel/algebra/relations/utilities/nil' require 'arel/algebra/relations/utilities/externalization' -require 'arel/algebra/relations/writes/delete' -require 'arel/algebra/relations/writes/update' -require 'arel/algebra/relations/writes/insert' +require 'arel/algebra/relations/writes' require 'arel/algebra/relations/operations/alias' require 'arel/algebra/relations/operations/group' require 'arel/algebra/relations/operations/join' diff --git a/lib/arel/algebra/relations/writes.rb b/lib/arel/algebra/relations/writes.rb new file mode 100644 index 0000000000..352f7bc7e5 --- /dev/null +++ b/lib/arel/algebra/relations/writes.rb @@ -0,0 +1,36 @@ +module Arel + class Deletion < Compound + attributes :relation + deriving :initialize, :== + + def call + engine.delete(self) + end + end + + class Insert < Compound + attributes :relation, :record + deriving :== + + def initialize(relation, record) + @relation, @record = relation, record.bind(relation) + end + + def call + engine.create(self) + end + end + + class Update < Compound + attributes :relation, :assignments + deriving :== + + def initialize(relation, assignments) + @relation, @assignments = relation, assignments.bind(relation) + end + + def call + engine.update(self) + end + end +end \ No newline at end of file diff --git a/lib/arel/algebra/relations/writes/delete.rb b/lib/arel/algebra/relations/writes/delete.rb deleted file mode 100644 index a94067c7fa..0000000000 --- a/lib/arel/algebra/relations/writes/delete.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Arel - class Deletion < Compound - attributes :relation - deriving :initialize, :== - - def call - engine.delete(self) - end - end -end diff --git a/lib/arel/algebra/relations/writes/insert.rb b/lib/arel/algebra/relations/writes/insert.rb deleted file mode 100644 index 6d85e9769a..0000000000 --- a/lib/arel/algebra/relations/writes/insert.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Arel - class Insert < Compound - attributes :relation, :record - deriving :== - - def initialize(relation, record) - @relation, @record = relation, record.bind(relation) - end - - def call - engine.create(self) - end - end -end diff --git a/lib/arel/algebra/relations/writes/update.rb b/lib/arel/algebra/relations/writes/update.rb deleted file mode 100644 index e647218a80..0000000000 --- a/lib/arel/algebra/relations/writes/update.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Arel - class Update < Compound - attributes :relation, :assignments - deriving :== - - def initialize(relation, assignments) - @relation, @assignments = relation, assignments - end - - def call - engine.update(self) - end - end -end diff --git a/lib/arel/engines/memory/predicates.rb b/lib/arel/engines/memory/predicates.rb index 3522ea3ffa..bbf39ba794 100644 --- a/lib/arel/engines/memory/predicates.rb +++ b/lib/arel/engines/memory/predicates.rb @@ -1,13 +1,4 @@ module Arel - class Predicate - def or(other_predicate) - Or.new(self, other_predicate) - end - - def and(other_predicate) - And.new(self, other_predicate) - end - end class Binary < Predicate def eval(row) @@ -30,11 +21,6 @@ module Arel end class Equality < Binary - def ==(other) - Equality === other and - ((operand1 == other.operand1 and operand2 == other.operand2) or - (operand1 == other.operand2 and operand2 == other.operand1)) - end end class GreaterThanOrEqualTo < Binary diff --git a/lib/arel/engines/memory/primitives.rb b/lib/arel/engines/memory/primitives.rb index 4d5c76e956..77d4c1a52c 100644 --- a/lib/arel/engines/memory/primitives.rb +++ b/lib/arel/engines/memory/primitives.rb @@ -1,2 +1,13 @@ -require 'arel/engines/memory/primitives/attribute' -require 'arel/engines/memory/primitives/value' +module Arel + class Attribute + def eval(row) + row[self] + end + end + + class Value + def eval(row) + value + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/memory/primitives/attribute.rb b/lib/arel/engines/memory/primitives/attribute.rb deleted file mode 100644 index 9864feadc2..0000000000 --- a/lib/arel/engines/memory/primitives/attribute.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Arel - class Attribute - def eval(row) - row[self] - end - end -end \ No newline at end of file diff --git a/lib/arel/engines/memory/primitives/value.rb b/lib/arel/engines/memory/primitives/value.rb deleted file mode 100644 index b83cd02e57..0000000000 --- a/lib/arel/engines/memory/primitives/value.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Arel - class Value - def eval(row) - value - end - end -end \ No newline at end of file diff --git a/lib/arel/engines/memory/relations.rb b/lib/arel/engines/memory/relations.rb index 6361d7c9d7..9f8264c439 100644 --- a/lib/arel/engines/memory/relations.rb +++ b/lib/arel/engines/memory/relations.rb @@ -1,2 +1,3 @@ require 'arel/engines/memory/relations/array' -require 'arel/engines/memory/relations/operations/where' +require 'arel/engines/memory/relations/operations' + diff --git a/lib/arel/engines/memory/relations/operations.rb b/lib/arel/engines/memory/relations/operations.rb new file mode 100644 index 0000000000..eb11fb55fd --- /dev/null +++ b/lib/arel/engines/memory/relations/operations.rb @@ -0,0 +1,7 @@ +module Arel + class Where < Compound + def eval + relation.eval.select { |row| predicate.eval(row) } + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/memory/relations/operations/where.rb b/lib/arel/engines/memory/relations/operations/where.rb deleted file mode 100644 index eb11fb55fd..0000000000 --- a/lib/arel/engines/memory/relations/operations/where.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Arel - class Where < Compound - def eval - relation.eval.select { |row| predicate.eval(row) } - end - end -end \ No newline at end of file diff --git a/lib/arel/engines/sql/primitives.rb b/lib/arel/engines/sql/primitives.rb index 405b1ca803..5544d63710 100644 --- a/lib/arel/engines/sql/primitives.rb +++ b/lib/arel/engines/sql/primitives.rb @@ -1,3 +1,31 @@ -require 'arel/engines/sql/primitives/attribute' -require 'arel/engines/sql/primitives/value' -require 'arel/engines/sql/primitives/expression' \ No newline at end of file +module Arel + class Attribute + def column + original_relation.column_for(self) + end + + def format(object) + object.to_sql(Sql::Attribute.new(self)) + end + + def to_sql(formatter = Sql::WhereCondition.new(relation)) + formatter.attribute self + end + end + + class Expression < Attribute + def to_sql(formatter = Sql::SelectClause.new(relation)) + formatter.expression self + end + end + + class Value + def to_sql(formatter = Sql::WhereCondition.new(relation)) + formatter.value value + end + + def format(object) + object.to_sql(Sql::Value.new(relation)) + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/primitives/attribute.rb b/lib/arel/engines/sql/primitives/attribute.rb deleted file mode 100644 index ad78a9ec5b..0000000000 --- a/lib/arel/engines/sql/primitives/attribute.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Arel - class Attribute - def column - original_relation.column_for(self) - end - - def format(object) - object.to_sql(Sql::Attribute.new(self)) - end - - def to_sql(formatter = Sql::WhereCondition.new(relation)) - formatter.attribute self - end - end -end \ No newline at end of file diff --git a/lib/arel/engines/sql/primitives/expression.rb b/lib/arel/engines/sql/primitives/expression.rb deleted file mode 100644 index 24f6879848..0000000000 --- a/lib/arel/engines/sql/primitives/expression.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Arel - class Expression < Attribute - def to_sql(formatter = Sql::SelectClause.new(relation)) - formatter.expression self - end - end -end \ No newline at end of file diff --git a/lib/arel/engines/sql/primitives/value.rb b/lib/arel/engines/sql/primitives/value.rb deleted file mode 100644 index a44acc26e0..0000000000 --- a/lib/arel/engines/sql/primitives/value.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Arel - class Value - def to_sql(formatter = Sql::WhereCondition.new(relation)) - formatter.value value - end - - def format(object) - object.to_sql(Sql::Value.new(relation)) - end - end -end \ No newline at end of file diff --git a/lib/arel/engines/sql/relations.rb b/lib/arel/engines/sql/relations.rb index 39ef8852a1..d6e4d295ba 100644 --- a/lib/arel/engines/sql/relations.rb +++ b/lib/arel/engines/sql/relations.rb @@ -5,6 +5,4 @@ require 'arel/engines/sql/relations/relation' require 'arel/engines/sql/relations/table' require 'arel/engines/sql/relations/operations/join' require 'arel/engines/sql/relations/operations/alias' -require 'arel/engines/sql/relations/writes/delete' -require 'arel/engines/sql/relations/writes/insert' -require 'arel/engines/sql/relations/writes/update' \ No newline at end of file +require 'arel/engines/sql/relations/writes' \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/writes.rb b/lib/arel/engines/sql/relations/writes.rb new file mode 100644 index 0000000000..edfd9f7233 --- /dev/null +++ b/lib/arel/engines/sql/relations/writes.rb @@ -0,0 +1,36 @@ +module Arel + class Deletion < Compound + 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 + end + + class Insert < Compound + def to_sql(formatter = nil) + [ + "INSERT", + "INTO #{table_sql}", + "(#{record.keys.collect { |key| engine.quote_column_name(key.name) }.join(', ')})", + "VALUES (#{record.collect { |key, value| key.format(value) }.join(', ')})" + ].join("\n") + end + end + + class Update < Compound + def to_sql(formatter = nil) + [ + "UPDATE #{table_sql} SET", + assignments.collect do |attribute, value| + "#{engine.quote_column_name(attribute.name)} = #{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 + end +end \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/writes/delete.rb b/lib/arel/engines/sql/relations/writes/delete.rb deleted file mode 100644 index b22ee51e24..0000000000 --- a/lib/arel/engines/sql/relations/writes/delete.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Arel - class Deletion < Compound - 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 - end -end \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/writes/insert.rb b/lib/arel/engines/sql/relations/writes/insert.rb deleted file mode 100644 index aac9c87a5b..0000000000 --- a/lib/arel/engines/sql/relations/writes/insert.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Arel - class Insert < Compound - def to_sql(formatter = nil) - [ - "INSERT", - "INTO #{table_sql}", - "(#{record.keys.collect { |key| engine.quote_column_name(key.name) }.join(', ')})", - "VALUES (#{record.collect { |key, value| key.format(value) }.join(', ')})" - ].join("\n") - end - end -end \ No newline at end of file diff --git a/lib/arel/engines/sql/relations/writes/update.rb b/lib/arel/engines/sql/relations/writes/update.rb deleted file mode 100644 index 3e35a0d5cc..0000000000 --- a/lib/arel/engines/sql/relations/writes/update.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Arel - class Update < Compound - def to_sql(formatter = nil) - [ - "UPDATE #{table_sql} SET", - assignments.collect do |attribute, value| - "#{engine.quote_column_name(attribute.name)} = #{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 - end -end \ No newline at end of file -- cgit v1.2.3 From 892337509b2bd269920dc567bc48c6a28c7222d2 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 14:46:08 -0400 Subject: removed function_sql in favor of polymorphism Conflicts: lib/arel/algebra/primitives/attribute.rb lib/arel/algebra/primitives/expression.rb spec/arel/unit/primitives/expression_spec.rb --- lib/arel/algebra/primitives/attribute.rb | 10 ++++----- lib/arel/algebra/primitives/expression.rb | 18 +++++++++++----- lib/arel/engines/sql/primitives.rb | 36 +++++++++++++++++++++++++------ 3 files changed, 48 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/arel/algebra/primitives/attribute.rb b/lib/arel/algebra/primitives/attribute.rb index 5e216770e4..943c5b030e 100644 --- a/lib/arel/algebra/primitives/attribute.rb +++ b/lib/arel/algebra/primitives/attribute.rb @@ -109,23 +109,23 @@ module Arel module Expressions def count(distinct = false) - distinct ? Expression.new(self, "DISTINCT").count : Expression.new(self, "COUNT") + distinct ? Distinct.new(self).count : Count.new(self) end def sum - Expression.new(self, "SUM") + Sum.new(self) end def maximum - Expression.new(self, "MAX") + Maximum.new(self) end def minimum - Expression.new(self, "MIN") + Minimum.new(self) end def average - Expression.new(self, "AVG") + Average.new(self) end end include Expressions diff --git a/lib/arel/algebra/primitives/expression.rb b/lib/arel/algebra/primitives/expression.rb index b67a5e1f8e..989397720c 100644 --- a/lib/arel/algebra/primitives/expression.rb +++ b/lib/arel/algebra/primitives/expression.rb @@ -1,12 +1,12 @@ module Arel class Expression < Attribute - attributes :attribute, :function_sql, :alias, :ancestor + attributes :attribute, :alias, :ancestor deriving :== delegate :relation, :to => :attribute alias_method :name, :alias - def initialize(attribute, function_sql, aliaz = nil, ancestor = nil) - @attribute, @function_sql, @alias, @ancestor = attribute, function_sql, aliaz, ancestor + def initialize(attribute, aliaz = nil, ancestor = nil) + @attribute, @alias, @ancestor = attribute, aliaz, ancestor end def aggregation? @@ -15,11 +15,11 @@ module Arel module Transformations def as(aliaz) - Expression.new(attribute, function_sql, aliaz, self) + self.class.new(attribute, aliaz, self) end def bind(new_relation) - new_relation == relation ? self : Expression.new(attribute.bind(new_relation), function_sql, @alias, self) + new_relation == relation ? self : self.class.new(attribute.bind(new_relation), @alias, self) end def to_attribute @@ -28,4 +28,12 @@ module Arel end include Transformations end + + class Count < Expression; end + class Distinct < Expression; end + class Sum < Expression; end + class Maximum < Expression; end + class Minimum < Expression; end + class Average < Expression; end end + diff --git a/lib/arel/engines/sql/primitives.rb b/lib/arel/engines/sql/primitives.rb index 5544d63710..c4968558a2 100644 --- a/lib/arel/engines/sql/primitives.rb +++ b/lib/arel/engines/sql/primitives.rb @@ -13,12 +13,6 @@ module Arel end end - class Expression < Attribute - def to_sql(formatter = Sql::SelectClause.new(relation)) - formatter.expression self - end - end - class Value def to_sql(formatter = Sql::WhereCondition.new(relation)) formatter.value value @@ -28,4 +22,34 @@ module Arel object.to_sql(Sql::Value.new(relation)) end end + + class Expression < Attribute + def to_sql(formatter = Sql::SelectClause.new(relation)) + formatter.expression self + end + end + + class Count < Expression + def function_sql; 'COUNT' end + end + + class Distinct < Expression + def function_sql; 'DISTINCT' end + end + + class Sum < Expression + def function_sql; 'SUM' end + end + + class Maximum < Expression + def function_sql; 'MAX' end + end + + class Minimum < Expression + def function_sql; 'MIN' end + end + + class Average < Expression + def function_sql; 'AVG' end + end end \ No newline at end of file -- cgit v1.2.3 From 3a6e8e5a3f99841691b70b89b0a10f836e6ec071 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 14:49:56 -0400 Subject: join sql stuff moved into sql adapter Conflicts: lib/arel/algebra/primitives/value.rb lib/arel/algebra/relations/operations/join.rb lib/arel/algebra/relations/relation.rb spec/arel/unit/relations/join_spec.rb --- lib/arel/algebra/primitives/value.rb | 1 - lib/arel/algebra/relations/operations/join.rb | 14 +++++++++++--- lib/arel/algebra/relations/relation.rb | 15 +++++++-------- lib/arel/algebra/relations/utilities/compound.rb | 3 +-- lib/arel/engines/sql/primitives.rb | 18 ++++++++++-------- lib/arel/engines/sql/relations/operations/join.rb | 14 ++++++++++++++ 6 files changed, 43 insertions(+), 22 deletions(-) (limited to 'lib') diff --git a/lib/arel/algebra/primitives/value.rb b/lib/arel/algebra/primitives/value.rb index 91c4045507..76c82890d0 100644 --- a/lib/arel/algebra/primitives/value.rb +++ b/lib/arel/algebra/primitives/value.rb @@ -2,7 +2,6 @@ module Arel class Value attributes :value, :relation deriving :initialize, :== - delegate :inclusion_predicate_sql, :equality_predicate_sql, :to => :value def bind(relation) Value.new(value, relation) diff --git a/lib/arel/algebra/relations/operations/join.rb b/lib/arel/algebra/relations/operations/join.rb index 8e19254378..695f360b51 100644 --- a/lib/arel/algebra/relations/operations/join.rb +++ b/lib/arel/algebra/relations/operations/join.rb @@ -1,12 +1,12 @@ module Arel class Join < Relation - attributes :join_sql, :relation1, :relation2, :predicates + attributes :relation1, :relation2, :predicates deriving :== delegate :engine, :name, :to => :relation1 hash_on :relation1 - def initialize(join_sql, relation1, relation2 = Nil.instance, *predicates) - @join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates + def initialize(relation1, relation2 = Nil.instance, *predicates) + @relation1, @relation2, @predicates = relation1, relation2, predicates end def attributes @@ -33,6 +33,14 @@ module Arel end end + class InnerJoin < Join; end + class OuterJoin < Join; end + class StringJoin < Join + def attributes + relation1.externalize.attributes + end + end + class Relation def join? false diff --git a/lib/arel/algebra/relations/relation.rb b/lib/arel/algebra/relations/relation.rb index 20badaf165..6d76e66638 100644 --- a/lib/arel/algebra/relations/relation.rb +++ b/lib/arel/algebra/relations/relation.rb @@ -32,28 +32,27 @@ module Arel include Enumerable module Operable - def join(other_relation = nil, join_type = "INNER JOIN") + def join(other_relation = nil, join_class = InnerJoin) case other_relation when String - Join.new(other_relation, self) + StringJoin.new(other_relation, self) when Relation - JoinOperation.new(join_type, self, other_relation) + JoinOperation.new(join_class, self, other_relation) else self end end def outer_join(other_relation = nil) - join(other_relation, "LEFT OUTER JOIN") + join(other_relation, OuterJoin) end [:where, :project, :order, :take, :skip, :group].each do |operation_name| - operation = <<-OPERATION + class_eval <<-OPERATION, __FILE__, __LINE__ def #{operation_name}(*arguments, &block) arguments.all?(&:blank?) && !block_given?? self : #{operation_name.to_s.classify}.new(self, *arguments, &block) end OPERATION - class_eval operation, __FILE__, __LINE__ end def alias @@ -75,9 +74,9 @@ module Arel end include Writable - JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do + JoinOperation = Struct.new(:join_class, :relation1, :relation2) do def on(*predicates) - Join.new(join_sql, relation1, relation2, *predicates) + join_class.new(relation1, relation2, *predicates) end end end diff --git a/lib/arel/algebra/relations/utilities/compound.rb b/lib/arel/algebra/relations/utilities/compound.rb index e33b8dbf14..fbff36a868 100644 --- a/lib/arel/algebra/relations/utilities/compound.rb +++ b/lib/arel/algebra/relations/utilities/compound.rb @@ -7,12 +7,11 @@ module Arel :to => :relation [:attributes, :wheres, :groupings, :orders].each do |operation_name| - operation = <<-OPERATION + class_eval <<-OPERATION, __FILE__, __LINE__ def #{operation_name} @#{operation_name} ||= relation.#{operation_name}.collect { |o| o.bind(self) } end OPERATION - class_eval operation, __FILE__, __LINE__ end end end diff --git a/lib/arel/engines/sql/primitives.rb b/lib/arel/engines/sql/primitives.rb index c4968558a2..6f89723afe 100644 --- a/lib/arel/engines/sql/primitives.rb +++ b/lib/arel/engines/sql/primitives.rb @@ -3,7 +3,7 @@ module Arel def column original_relation.column_for(self) end - + def format(object) object.to_sql(Sql::Attribute.new(self)) end @@ -14,6 +14,8 @@ module Arel end class Value + delegate :inclusion_predicate_sql, :equality_predicate_sql, :to => :value + def to_sql(formatter = Sql::WhereCondition.new(relation)) formatter.value value end @@ -22,33 +24,33 @@ module Arel object.to_sql(Sql::Value.new(relation)) end end - + class Expression < Attribute def to_sql(formatter = Sql::SelectClause.new(relation)) formatter.expression self end end - + class Count < Expression def function_sql; 'COUNT' end end - + class Distinct < Expression def function_sql; 'DISTINCT' end end - + class Sum < Expression def function_sql; 'SUM' end end - + class Maximum < Expression def function_sql; 'MAX' end end - + class Minimum < Expression def function_sql; 'MIN' end end - + class Average < Expression def function_sql; 'AVG' end end diff --git a/lib/arel/engines/sql/relations/operations/join.rb b/lib/arel/engines/sql/relations/operations/join.rb index be21119bc9..2f5e23644e 100644 --- a/lib/arel/engines/sql/relations/operations/join.rb +++ b/lib/arel/engines/sql/relations/operations/join.rb @@ -16,4 +16,18 @@ module Arel end end end + + class InnerJoin < Join + def join_sql; "INNER JOIN" end + end + + class OuterJoin < Join + def join_sql; "OUTER JOIN" end + end + + class StringJoin < Join + def joins(_, __ = nil) + relation2 + end + end end \ No newline at end of file -- cgit v1.2.3 From 437429764510338bdc5f4915286425f07565a573 Mon Sep 17 00:00:00 2001 From: Nick Kallen Date: Mon, 26 May 2008 14:30:51 -0700 Subject: moved table-related stuff into sql engine --- lib/arel/algebra/relations/utilities/compound.rb | 2 +- lib/arel/engines/sql/relations.rb | 1 + lib/arel/engines/sql/relations/utilities/compound.rb | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 lib/arel/engines/sql/relations/utilities/compound.rb (limited to 'lib') diff --git a/lib/arel/algebra/relations/utilities/compound.rb b/lib/arel/algebra/relations/utilities/compound.rb index fbff36a868..4d7cece812 100644 --- a/lib/arel/algebra/relations/utilities/compound.rb +++ b/lib/arel/algebra/relations/utilities/compound.rb @@ -3,7 +3,7 @@ module Arel attr_reader :relation hash_on :relation delegate :joins, :join?, :inserts, :taken, :skipped, :name, :externalizable?, - :column_for, :engine, :table, :table_sql, :array, + :column_for, :engine, :to => :relation [:attributes, :wheres, :groupings, :orders].each do |operation_name| diff --git a/lib/arel/engines/sql/relations.rb b/lib/arel/engines/sql/relations.rb index d6e4d295ba..0eb1303ec9 100644 --- a/lib/arel/engines/sql/relations.rb +++ b/lib/arel/engines/sql/relations.rb @@ -1,3 +1,4 @@ +require 'arel/engines/sql/relations/utilities/compound' require 'arel/engines/sql/relations/utilities/recursion' require 'arel/engines/sql/relations/utilities/externalization' require 'arel/engines/sql/relations/utilities/nil' diff --git a/lib/arel/engines/sql/relations/utilities/compound.rb b/lib/arel/engines/sql/relations/utilities/compound.rb new file mode 100644 index 0000000000..502bf8b01e --- /dev/null +++ b/lib/arel/engines/sql/relations/utilities/compound.rb @@ -0,0 +1,6 @@ +module Arel + class Compound < Relation + delegate :table, :table_sql, :array, :to => :relation + end +end + \ No newline at end of file -- cgit v1.2.3 From 4e3c9a01307339916f6b947d24f19b0f442afd78 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 14:58:46 -0400 Subject: most in memory operations save join and group Conflicts: lib/arel/algebra/extensions/object.rb lib/arel/algebra/primitives/value.rb lib/arel/engines/memory/relations.rb lib/arel/engines/sql/formatters.rb lib/arel/engines/sql/primitives.rb spec/arel/unit/relations/alias_spec.rb spec/arel/unit/relations/array_spec.rb spec/arel/unit/relations/order_spec.rb --- lib/arel/algebra/extensions/array.rb | 7 +++++ lib/arel/algebra/extensions/hash.rb | 7 +++++ lib/arel/algebra/extensions/object.rb | 5 ++++ lib/arel/algebra/primitives.rb | 1 + lib/arel/algebra/primitives/attribute.rb | 17 +++++++++++ lib/arel/algebra/primitives/ordering.rb | 18 ++++++++++++ lib/arel/algebra/primitives/value.rb | 8 ++---- lib/arel/algebra/relations/operations/order.rb | 3 +- lib/arel/engines/memory/primitives.rb | 14 +++++++++ lib/arel/engines/memory/relations.rb | 1 + lib/arel/engines/memory/relations/compound.rb | 5 ++++ lib/arel/engines/memory/relations/operations.rb | 33 ++++++++++++++++++++++ lib/arel/engines/sql/formatters.rb | 6 ++-- lib/arel/engines/sql/primitives.rb | 14 +++++++++ .../engines/sql/relations/utilities/compound.rb | 2 +- 15 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 lib/arel/algebra/primitives/ordering.rb create mode 100644 lib/arel/engines/memory/relations/compound.rb (limited to 'lib') diff --git a/lib/arel/algebra/extensions/array.rb b/lib/arel/algebra/extensions/array.rb index 5b6d6d6abd..935569a07b 100644 --- a/lib/arel/algebra/extensions/array.rb +++ b/lib/arel/algebra/extensions/array.rb @@ -2,4 +2,11 @@ class Array def to_hash Hash[*flatten] end + + def group_by + inject({}) do |groups, element| + (groups[yield(element)] ||= []) << element + groups + end + end end \ No newline at end of file diff --git a/lib/arel/algebra/extensions/hash.rb b/lib/arel/algebra/extensions/hash.rb index 7472b5aa73..bc97785e62 100644 --- a/lib/arel/algebra/extensions/hash.rb +++ b/lib/arel/algebra/extensions/hash.rb @@ -4,4 +4,11 @@ class Hash bound.merge(key.bind(relation) => value.bind(relation)) end end + + def slice(*attributes) + inject({}) do |cheese, (key, value)| + cheese[key] = value if attributes.include?(key) + cheese + end + end end \ No newline at end of file diff --git a/lib/arel/algebra/extensions/object.rb b/lib/arel/algebra/extensions/object.rb index d626407dcb..efdbbf525f 100644 --- a/lib/arel/algebra/extensions/object.rb +++ b/lib/arel/algebra/extensions/object.rb @@ -12,4 +12,9 @@ class Object self end end + + def let + yield(self) + end end + diff --git a/lib/arel/algebra/primitives.rb b/lib/arel/algebra/primitives.rb index a4c3169e0b..df8d16a5d5 100644 --- a/lib/arel/algebra/primitives.rb +++ b/lib/arel/algebra/primitives.rb @@ -1,4 +1,5 @@ require 'arel/algebra/primitives/attribute' +require 'arel/algebra/primitives/ordering' require 'arel/algebra/primitives/value' require 'arel/algebra/primitives/expression' diff --git a/lib/arel/algebra/primitives/attribute.rb b/lib/arel/algebra/primitives/attribute.rb index 943c5b030e..7a4411e248 100644 --- a/lib/arel/algebra/primitives/attribute.rb +++ b/lib/arel/algebra/primitives/attribute.rb @@ -17,6 +17,10 @@ module Arel def aggregation? false end + + def inspect + "" + end module Transformations def self.included(klass) @@ -129,5 +133,18 @@ module Arel end end include Expressions + + module Orderings + def asc + Ascending.new(self) + end + + def desc + Descending.new(self) + end + + alias_method :to_ordering, :asc + end + include Orderings end end diff --git a/lib/arel/algebra/primitives/ordering.rb b/lib/arel/algebra/primitives/ordering.rb new file mode 100644 index 0000000000..e8d8f97188 --- /dev/null +++ b/lib/arel/algebra/primitives/ordering.rb @@ -0,0 +1,18 @@ +module Arel + class Ordering + attributes :attribute + deriving :initialize, :== + delegate :relation, :to => :attribute + + def bind(relation) + self.class.new(attribute.bind(relation)) + end + + def to_ordering + self + end + end + + class Ascending < Ordering; end + class Descending < Ordering; end +end \ No newline at end of file diff --git a/lib/arel/algebra/primitives/value.rb b/lib/arel/algebra/primitives/value.rb index 76c82890d0..e363805140 100644 --- a/lib/arel/algebra/primitives/value.rb +++ b/lib/arel/algebra/primitives/value.rb @@ -7,12 +7,8 @@ module Arel Value.new(value, relation) end - def aggregation? - false - end - - def to_attribute - value + def to_ordering + self end end end diff --git a/lib/arel/algebra/relations/operations/order.rb b/lib/arel/algebra/relations/operations/order.rb index 05af3fde4d..eccd8bcda0 100644 --- a/lib/arel/algebra/relations/operations/order.rb +++ b/lib/arel/algebra/relations/operations/order.rb @@ -10,7 +10,8 @@ module Arel # TESTME def orders - (orderings + relation.orders).collect { |o| o.bind(self) } + # QUESTION - do we still need relation.orders ? + (orderings + relation.orders).collect { |o| o.bind(self) }.collect { |o| o.to_ordering } end end end \ No newline at end of file diff --git a/lib/arel/engines/memory/primitives.rb b/lib/arel/engines/memory/primitives.rb index 77d4c1a52c..f8bbcedb55 100644 --- a/lib/arel/engines/memory/primitives.rb +++ b/lib/arel/engines/memory/primitives.rb @@ -10,4 +10,18 @@ module Arel value end end + + class Ordering + def eval(row1, row2) + (attribute.eval(row1) <=> attribute.eval(row2)) * direction + end + end + + class Descending < Ordering + def direction; -1 end + end + + class Ascending < Ordering + def direction; 1 end + end end \ No newline at end of file diff --git a/lib/arel/engines/memory/relations.rb b/lib/arel/engines/memory/relations.rb index 9f8264c439..1b009537b9 100644 --- a/lib/arel/engines/memory/relations.rb +++ b/lib/arel/engines/memory/relations.rb @@ -1,3 +1,4 @@ require 'arel/engines/memory/relations/array' require 'arel/engines/memory/relations/operations' +require 'arel/engines/memory/relations/compound' diff --git a/lib/arel/engines/memory/relations/compound.rb b/lib/arel/engines/memory/relations/compound.rb new file mode 100644 index 0000000000..b029082d57 --- /dev/null +++ b/lib/arel/engines/memory/relations/compound.rb @@ -0,0 +1,5 @@ +module Arel + class Compound < Relation + delegate :array, :to => :relation + end +end diff --git a/lib/arel/engines/memory/relations/operations.rb b/lib/arel/engines/memory/relations/operations.rb index eb11fb55fd..115df054df 100644 --- a/lib/arel/engines/memory/relations/operations.rb +++ b/lib/arel/engines/memory/relations/operations.rb @@ -4,4 +4,37 @@ module Arel relation.eval.select { |row| predicate.eval(row) } end end + + class Order < Compound + def eval + relation.eval.sort do |row1, row2| + ordering = orderings.detect { |o| o.eval(row1, row2) != 0 } || orderings.last + ordering.eval(row1, row2) + end + end + end + + class Project < Compound + def eval + relation.eval.collect { |r| r.slice(*projections) } + end + end + + class Take < Compound + def eval + relation.eval[0, taken] + end + end + + class Skip < Compound + def eval + relation.eval[skipped..-1] + end + end + + class Group < Compound + def eval + raise NotImplementedError + end + end end \ No newline at end of file diff --git a/lib/arel/engines/sql/formatters.rb b/lib/arel/engines/sql/formatters.rb index f82ddf631f..bc5f0f7c64 100644 --- a/lib/arel/engines/sql/formatters.rb +++ b/lib/arel/engines/sql/formatters.rb @@ -47,9 +47,9 @@ module Arel class WhereClause < PassThrough end - class OrderClause < PassThrough - def attribute(attribute) - "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" + class OrderClause < PassThrough + def ordering(ordering) + "#{quote_table_name(name_for(ordering.attribute.original_relation))}.#{quote_column_name(ordering.attribute.name)} #{ordering.direction_sql}" end end diff --git a/lib/arel/engines/sql/primitives.rb b/lib/arel/engines/sql/primitives.rb index 6f89723afe..9e9143ac0f 100644 --- a/lib/arel/engines/sql/primitives.rb +++ b/lib/arel/engines/sql/primitives.rb @@ -24,6 +24,20 @@ module Arel object.to_sql(Sql::Value.new(relation)) end end + + class Ordering + def to_sql(formatter = Sql::OrderClause.new(relation)) + formatter.ordering self + end + end + + class Ascending < Ordering + def direction_sql; 'ASC' end + end + + class Descending < Ordering + def direction_sql; 'DESC' end + end class Expression < Attribute def to_sql(formatter = Sql::SelectClause.new(relation)) diff --git a/lib/arel/engines/sql/relations/utilities/compound.rb b/lib/arel/engines/sql/relations/utilities/compound.rb index 502bf8b01e..61df196d6e 100644 --- a/lib/arel/engines/sql/relations/utilities/compound.rb +++ b/lib/arel/engines/sql/relations/utilities/compound.rb @@ -1,6 +1,6 @@ module Arel class Compound < Relation - delegate :table, :table_sql, :array, :to => :relation + delegate :table, :table_sql, :to => :relation end end \ No newline at end of file -- cgit v1.2.3 From 9d77c08cf8a75636b058c1b85af52ef96e07cee5 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 15:00:10 -0400 Subject: made block stuff read nicer Conflicts: doc/TODO --- lib/arel/algebra/relations/operations/group.rb | 3 ++- lib/arel/algebra/relations/operations/order.rb | 3 ++- lib/arel/algebra/relations/operations/project.rb | 3 ++- lib/arel/algebra/relations/utilities/compound.rb | 5 +++++ 4 files changed, 11 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/arel/algebra/relations/operations/group.rb b/lib/arel/algebra/relations/operations/group.rb index 04fd9fea62..879f2352c5 100644 --- a/lib/arel/algebra/relations/operations/group.rb +++ b/lib/arel/algebra/relations/operations/group.rb @@ -5,7 +5,8 @@ module Arel def initialize(relation, *groupings, &block) @relation = relation - @groupings = (groupings + (block_given?? [yield(relatoin)] : [])).collect { |g| g.bind(relation) } + @groupings = (groupings + arguments_from_block(relation, &block)) \ + .collect { |g| g.bind(relation) } end def externalizable? diff --git a/lib/arel/algebra/relations/operations/order.rb b/lib/arel/algebra/relations/operations/order.rb index eccd8bcda0..4e7133f5a8 100644 --- a/lib/arel/algebra/relations/operations/order.rb +++ b/lib/arel/algebra/relations/operations/order.rb @@ -5,7 +5,8 @@ module Arel def initialize(relation, *orderings, &block) @relation = relation - @orderings = (orderings + (block_given?? [yield(relation)] : [])).collect { |o| o.bind(relation) } + @orderings = (orderings + arguments_from_block(relation, &block)) \ + .collect { |o| o.bind(relation) } end # TESTME diff --git a/lib/arel/algebra/relations/operations/project.rb b/lib/arel/algebra/relations/operations/project.rb index 5507ea3163..223d320e22 100644 --- a/lib/arel/algebra/relations/operations/project.rb +++ b/lib/arel/algebra/relations/operations/project.rb @@ -5,7 +5,8 @@ module Arel def initialize(relation, *projections, &block) @relation = relation - @projections = (projections + (block_given?? [yield(relation)] : [])).collect { |p| p.bind(relation) } + @projections = (projections + arguments_from_block(relation, &block)) \ + .collect { |p| p.bind(relation) } end def attributes diff --git a/lib/arel/algebra/relations/utilities/compound.rb b/lib/arel/algebra/relations/utilities/compound.rb index 4d7cece812..99c3d02748 100644 --- a/lib/arel/algebra/relations/utilities/compound.rb +++ b/lib/arel/algebra/relations/utilities/compound.rb @@ -13,5 +13,10 @@ module Arel end OPERATION end + + private + def arguments_from_block(relation, &block) + block_given?? [yield(relation)] : [] + end end end -- cgit v1.2.3 From 8339f024c7663133a78c4d0a8824b5b6fafaf239 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 15:42:42 -0400 Subject: recursive memory operations now possible Conflicts: lib/arel/algebra/relations/relation.rb --- lib/arel/algebra/extensions/hash.rb | 7 ------- lib/arel/algebra/relations.rb | 1 + lib/arel/algebra/relations/relation.rb | 4 ---- lib/arel/algebra/relations/row.rb | 21 +++++++++++++++++++++ lib/arel/engines/memory/predicates.rb | 6 ++++++ lib/arel/engines/memory/relations.rb | 1 + lib/arel/engines/memory/relations/array.rb | 2 +- lib/arel/engines/memory/relations/compound.rb | 4 ++++ lib/arel/engines/memory/relations/operations.rb | 10 +++++----- lib/arel/engines/memory/relations/relation.rb | 7 +++++++ 10 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 lib/arel/algebra/relations/row.rb create mode 100644 lib/arel/engines/memory/relations/relation.rb (limited to 'lib') diff --git a/lib/arel/algebra/extensions/hash.rb b/lib/arel/algebra/extensions/hash.rb index bc97785e62..7472b5aa73 100644 --- a/lib/arel/algebra/extensions/hash.rb +++ b/lib/arel/algebra/extensions/hash.rb @@ -4,11 +4,4 @@ class Hash bound.merge(key.bind(relation) => value.bind(relation)) end end - - def slice(*attributes) - inject({}) do |cheese, (key, value)| - cheese[key] = value if attributes.include?(key) - cheese - end - end end \ No newline at end of file diff --git a/lib/arel/algebra/relations.rb b/lib/arel/algebra/relations.rb index b75a31e5e3..94df5938fe 100644 --- a/lib/arel/algebra/relations.rb +++ b/lib/arel/algebra/relations.rb @@ -2,6 +2,7 @@ require 'arel/algebra/relations/relation' require 'arel/algebra/relations/utilities/compound' require 'arel/algebra/relations/utilities/nil' require 'arel/algebra/relations/utilities/externalization' +require 'arel/algebra/relations/row' require 'arel/algebra/relations/writes' require 'arel/algebra/relations/operations/alias' require 'arel/algebra/relations/operations/group' diff --git a/lib/arel/algebra/relations/relation.rb b/lib/arel/algebra/relations/relation.rb index 6d76e66638..fe8cab4b02 100644 --- a/lib/arel/algebra/relations/relation.rb +++ b/lib/arel/algebra/relations/relation.rb @@ -14,10 +14,6 @@ module Arel self end - def root - self - end - module Enumerable include ::Enumerable diff --git a/lib/arel/algebra/relations/row.rb b/lib/arel/algebra/relations/row.rb new file mode 100644 index 0000000000..2d63498452 --- /dev/null +++ b/lib/arel/algebra/relations/row.rb @@ -0,0 +1,21 @@ +module Arel + class Row + attributes :relation, :tuple + deriving :==, :initialize + + def [](attribute) + tuple[relation.position_of(attribute)] + end + + def slice(*attributes) + Row.new(relation, attributes.inject([]) do |cheese, attribute| + cheese << self[attribute] + cheese + end) + end + + def bind(relation) + Row.new(relation, tuple) + end + end +end \ No newline at end of file diff --git a/lib/arel/engines/memory/predicates.rb b/lib/arel/engines/memory/predicates.rb index bbf39ba794..e233f3ba39 100644 --- a/lib/arel/engines/memory/predicates.rb +++ b/lib/arel/engines/memory/predicates.rb @@ -21,15 +21,19 @@ module Arel end class Equality < Binary + def operator; :== end end class GreaterThanOrEqualTo < Binary + def operator; :>= end end class GreaterThan < Binary + def operator; :> end end class LessThanOrEqualTo < Binary + def operator; :<= end end class LessThan < Binary @@ -37,8 +41,10 @@ module Arel end class Match < Binary + def operator; :=~ end end class In < Binary + def operator; :include? end end end diff --git a/lib/arel/engines/memory/relations.rb b/lib/arel/engines/memory/relations.rb index 1b009537b9..820b0af4b2 100644 --- a/lib/arel/engines/memory/relations.rb +++ b/lib/arel/engines/memory/relations.rb @@ -1,3 +1,4 @@ +require 'arel/engines/memory/relations/relation' require 'arel/engines/memory/relations/array' require 'arel/engines/memory/relations/operations' require 'arel/engines/memory/relations/compound' diff --git a/lib/arel/engines/memory/relations/array.rb b/lib/arel/engines/memory/relations/array.rb index c02c62891b..ea0b5af5ba 100644 --- a/lib/arel/engines/memory/relations/array.rb +++ b/lib/arel/engines/memory/relations/array.rb @@ -15,7 +15,7 @@ module Arel end def eval - @array.collect { |row| attributes.zip(row).to_hash } + @array.collect { |r| Row.new(self, r) } end end end \ No newline at end of file diff --git a/lib/arel/engines/memory/relations/compound.rb b/lib/arel/engines/memory/relations/compound.rb index b029082d57..3791fa4622 100644 --- a/lib/arel/engines/memory/relations/compound.rb +++ b/lib/arel/engines/memory/relations/compound.rb @@ -1,5 +1,9 @@ module Arel class Compound < Relation delegate :array, :to => :relation + + def unoperated_rows + relation.eval.collect { |row| row.bind(self) } + end end end diff --git a/lib/arel/engines/memory/relations/operations.rb b/lib/arel/engines/memory/relations/operations.rb index 115df054df..8e03aca7b1 100644 --- a/lib/arel/engines/memory/relations/operations.rb +++ b/lib/arel/engines/memory/relations/operations.rb @@ -1,13 +1,13 @@ module Arel class Where < Compound def eval - relation.eval.select { |row| predicate.eval(row) } + unoperated_rows.select { |row| predicate.eval(row) } end end class Order < Compound def eval - relation.eval.sort do |row1, row2| + unoperated_rows.sort do |row1, row2| ordering = orderings.detect { |o| o.eval(row1, row2) != 0 } || orderings.last ordering.eval(row1, row2) end @@ -16,19 +16,19 @@ module Arel class Project < Compound def eval - relation.eval.collect { |r| r.slice(*projections) } + unoperated_rows.collect { |r| r.slice(*projections) } end end class Take < Compound def eval - relation.eval[0, taken] + unoperated_rows[0, taken] end end class Skip < Compound def eval - relation.eval[skipped..-1] + unoperated_rows[skipped..-1] end end diff --git a/lib/arel/engines/memory/relations/relation.rb b/lib/arel/engines/memory/relations/relation.rb new file mode 100644 index 0000000000..abfb8bb37f --- /dev/null +++ b/lib/arel/engines/memory/relations/relation.rb @@ -0,0 +1,7 @@ +module Arel + class Relation + def position_of(attribute) + attributes.index(self[attribute]) + end + end +end \ No newline at end of file -- cgit v1.2.3 From 2fe585328d6a24df310d3e60059c9c7b05b64bac Mon Sep 17 00:00:00 2001 From: Nick Kallen Date: Tue, 27 May 2008 14:19:59 -0700 Subject: performing in memory joins --- lib/arel/algebra/relations/row.rb | 4 ++++ lib/arel/engines/memory/relations/operations.rb | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'lib') diff --git a/lib/arel/algebra/relations/row.rb b/lib/arel/algebra/relations/row.rb index 2d63498452..3731dd9696 100644 --- a/lib/arel/algebra/relations/row.rb +++ b/lib/arel/algebra/relations/row.rb @@ -17,5 +17,9 @@ module Arel def bind(relation) Row.new(relation, tuple) end + + def combine(other, relation) + Row.new(relation, tuple + other.tuple) + end end end \ No newline at end of file diff --git a/lib/arel/engines/memory/relations/operations.rb b/lib/arel/engines/memory/relations/operations.rb index 8e03aca7b1..e35fbe3234 100644 --- a/lib/arel/engines/memory/relations/operations.rb +++ b/lib/arel/engines/memory/relations/operations.rb @@ -37,4 +37,25 @@ module Arel raise NotImplementedError end end + + class Alias < Compound + def eval + unoperated_rows + end + end + + class Join < Relation + def eval + result = [] + relation1.eval.each do |row1| + relation2.eval.each do |row2| + combined_row = row1.combine(row2, self) + if predicates.all? { |p| p.eval(combined_row) } + result << combined_row + end + end + end + result + end + end end \ No newline at end of file -- cgit v1.2.3 From 20b28b441b651d0404d64049253898c061a039be Mon Sep 17 00:00:00 2001 From: Nick Kallen Date: Tue, 27 May 2008 14:37:11 -0700 Subject: using in memory relations as results from sql relation Conflicts: lib/arel/algebra/primitives/expression.rb lib/arel/algebra/relations/relation.rb --- lib/arel/algebra/extensions.rb | 1 + lib/arel/algebra/extensions/symbol.rb | 5 +++++ lib/arel/algebra/primitives/attribute.rb | 4 ++-- lib/arel/algebra/primitives/expression.rb | 2 +- lib/arel/algebra/relations/relation.rb | 11 +++++++++-- lib/arel/algebra/relations/utilities/externalization.rb | 2 +- lib/arel/engines/memory/relations.rb | 1 - lib/arel/engines/memory/relations/array.rb | 4 ++-- lib/arel/engines/memory/relations/relation.rb | 7 ------- lib/arel/engines/sql/engine.rb | 10 +++++----- lib/arel/engines/sql/relations/operations/join.rb | 2 +- 11 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 lib/arel/algebra/extensions/symbol.rb delete mode 100644 lib/arel/engines/memory/relations/relation.rb (limited to 'lib') diff --git a/lib/arel/algebra/extensions.rb b/lib/arel/algebra/extensions.rb index 5338fee989..694dc60a2a 100644 --- a/lib/arel/algebra/extensions.rb +++ b/lib/arel/algebra/extensions.rb @@ -1,4 +1,5 @@ require 'arel/algebra/extensions/object' require 'arel/algebra/extensions/class' require 'arel/algebra/extensions/array' +require 'arel/algebra/extensions/symbol' require 'arel/algebra/extensions/hash' diff --git a/lib/arel/algebra/extensions/symbol.rb b/lib/arel/algebra/extensions/symbol.rb new file mode 100644 index 0000000000..787867bdc3 --- /dev/null +++ b/lib/arel/algebra/extensions/symbol.rb @@ -0,0 +1,5 @@ +class Symbol + def to_attribute(relation) + Arel::Attribute.new(relation, self) + end +end \ No newline at end of file diff --git a/lib/arel/algebra/primitives/attribute.rb b/lib/arel/algebra/primitives/attribute.rb index 7a4411e248..aa1f2ae00c 100644 --- a/lib/arel/algebra/primitives/attribute.rb +++ b/lib/arel/algebra/primitives/attribute.rb @@ -39,8 +39,8 @@ module Arel relation == new_relation ? self : Attribute.new(new_relation, name, :alias => @alias, :ancestor => self) end - def to_attribute - self + def to_attribute(relation) + bind(relation) end end include Transformations diff --git a/lib/arel/algebra/primitives/expression.rb b/lib/arel/algebra/primitives/expression.rb index 989397720c..5566e2d0b7 100644 --- a/lib/arel/algebra/primitives/expression.rb +++ b/lib/arel/algebra/primitives/expression.rb @@ -22,7 +22,7 @@ module Arel new_relation == relation ? self : self.class.new(attribute.bind(new_relation), @alias, self) end - def to_attribute + def to_attribute(relation) Attribute.new(relation, @alias, :ancestor => self) end end diff --git a/lib/arel/algebra/relations/relation.rb b/lib/arel/algebra/relations/relation.rb index fe8cab4b02..c38ab0e9c5 100644 --- a/lib/arel/algebra/relations/relation.rb +++ b/lib/arel/algebra/relations/relation.rb @@ -31,7 +31,7 @@ module Arel def join(other_relation = nil, join_class = InnerJoin) case other_relation when String - StringJoin.new(other_relation, self) + StringJoin.new(self, other_relation) when Relation JoinOperation.new(join_class, self, other_relation) else @@ -85,7 +85,8 @@ module Arel find_attribute_matching_name(index) when Attribute, Expression find_attribute_matching_attribute(index) - when Array + when ::Array + # TESTME index.collect { |i| self[i] } end end @@ -100,6 +101,12 @@ module Arel end end + def position_of(attribute) + (@position_of ||= Hash.new do |h, attribute| + h[attribute] = attributes.index(self[attribute]) + end)[attribute] + end + private def matching_attributes(attribute) (@matching_attributes ||= attributes.inject({}) do |hash, a| diff --git a/lib/arel/algebra/relations/utilities/externalization.rb b/lib/arel/algebra/relations/utilities/externalization.rb index bd067f2304..13758ccec9 100644 --- a/lib/arel/algebra/relations/utilities/externalization.rb +++ b/lib/arel/algebra/relations/utilities/externalization.rb @@ -8,7 +8,7 @@ module Arel end def attributes - @attributes ||= relation.attributes.collect(&:to_attribute).collect { |a| a.bind(self) } + @attributes ||= relation.attributes.collect { |a| a.to_attribute(self) } end end diff --git a/lib/arel/engines/memory/relations.rb b/lib/arel/engines/memory/relations.rb index 820b0af4b2..1b009537b9 100644 --- a/lib/arel/engines/memory/relations.rb +++ b/lib/arel/engines/memory/relations.rb @@ -1,4 +1,3 @@ -require 'arel/engines/memory/relations/relation' require 'arel/engines/memory/relations/array' require 'arel/engines/memory/relations/operations' require 'arel/engines/memory/relations/compound' diff --git a/lib/arel/engines/memory/relations/array.rb b/lib/arel/engines/memory/relations/array.rb index ea0b5af5ba..15a3e95e1b 100644 --- a/lib/arel/engines/memory/relations/array.rb +++ b/lib/arel/engines/memory/relations/array.rb @@ -1,8 +1,8 @@ module Arel class Array < Relation attributes :array, :attribute_names - deriving :initialize include Recursion::BaseCase + deriving :==, :initialize def engine @engine ||= Memory::Engine.new @@ -10,7 +10,7 @@ module Arel def attributes @attributes ||= @attribute_names.collect do |name| - Attribute.new(self, name.to_sym) + name.to_attribute(self) end end diff --git a/lib/arel/engines/memory/relations/relation.rb b/lib/arel/engines/memory/relations/relation.rb deleted file mode 100644 index abfb8bb37f..0000000000 --- a/lib/arel/engines/memory/relations/relation.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Arel - class Relation - def position_of(attribute) - attributes.index(self[attribute]) - end - end -end \ No newline at end of file diff --git a/lib/arel/engines/sql/engine.rb b/lib/arel/engines/sql/engine.rb index e5d1a8b0ca..0700ae9733 100644 --- a/lib/arel/engines/sql/engine.rb +++ b/lib/arel/engines/sql/engine.rb @@ -19,12 +19,12 @@ module Arel end def read(relation) - results = connection.execute(relation.to_sql) - rows = [] - results.each do |row| - rows << attributes.zip(row).to_hash + # FIXME + class << rows = connection.execute(relation.to_sql) + include Enumerable end - rows + + Array.new(rows, relation.attributes) end def update(relation) diff --git a/lib/arel/engines/sql/relations/operations/join.rb b/lib/arel/engines/sql/relations/operations/join.rb index 2f5e23644e..f848fd3268 100644 --- a/lib/arel/engines/sql/relations/operations/join.rb +++ b/lib/arel/engines/sql/relations/operations/join.rb @@ -22,7 +22,7 @@ module Arel end class OuterJoin < Join - def join_sql; "OUTER JOIN" end + def join_sql; "LEFT OUTER JOIN" end end class StringJoin < Join -- cgit v1.2.3 From 07833d39c2885a5cddf38eeb860d79353c0f447b Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 15:47:10 -0400 Subject: basic implementation of in memory insertions Conflicts: lib/arel/engines/memory/relations.rb --- lib/arel/algebra/relations/relation.rb | 2 +- lib/arel/engines/memory/engine.rb | 4 ++++ lib/arel/engines/memory/relations.rb | 1 + lib/arel/engines/memory/relations/writes.rb | 7 +++++++ lib/arel/session.rb | 3 +++ 5 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 lib/arel/engines/memory/relations/writes.rb (limited to 'lib') diff --git a/lib/arel/algebra/relations/relation.rb b/lib/arel/algebra/relations/relation.rb index c38ab0e9c5..9fdac26528 100644 --- a/lib/arel/algebra/relations/relation.rb +++ b/lib/arel/algebra/relations/relation.rb @@ -57,7 +57,7 @@ module Arel module Writable def insert(record) - session.create Insert.new(self, record); self + session.create Insert.new(self, record) end def update(assignments) diff --git a/lib/arel/engines/memory/engine.rb b/lib/arel/engines/memory/engine.rb index 67a084f2cd..c8f79c9d57 100644 --- a/lib/arel/engines/memory/engine.rb +++ b/lib/arel/engines/memory/engine.rb @@ -5,6 +5,10 @@ module Arel def read(relation) relation.eval end + + def create(relation) + relation.eval + end end include CRUD end diff --git a/lib/arel/engines/memory/relations.rb b/lib/arel/engines/memory/relations.rb index 1b009537b9..c67af2d63b 100644 --- a/lib/arel/engines/memory/relations.rb +++ b/lib/arel/engines/memory/relations.rb @@ -1,4 +1,5 @@ require 'arel/engines/memory/relations/array' require 'arel/engines/memory/relations/operations' +require 'arel/engines/memory/relations/writes' require 'arel/engines/memory/relations/compound' diff --git a/lib/arel/engines/memory/relations/writes.rb b/lib/arel/engines/memory/relations/writes.rb new file mode 100644 index 0000000000..fa8b84a32c --- /dev/null +++ b/lib/arel/engines/memory/relations/writes.rb @@ -0,0 +1,7 @@ +module Arel + class Insert < Compound + def eval + unoperated_rows + [Row.new(self, record.values.collect(&:value))] + end + end +end \ No newline at end of file diff --git a/lib/arel/session.rb b/lib/arel/session.rb index cf04e8a93a..921ad0a7ac 100644 --- a/lib/arel/session.rb +++ b/lib/arel/session.rb @@ -24,6 +24,7 @@ module Arel module CRUD def create(insert) insert.call + insert end def read(select) @@ -34,10 +35,12 @@ module Arel def update(update) update.call + update end def delete(delete) delete.call + delete end end include CRUD -- cgit v1.2.3 From 7a51983efc50c8f9092785b1b586f8884dedc01a Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 16:02:10 -0400 Subject: initial implementation of cross-engine join Conflicts: lib/arel/engines/memory/relations/array.rb lib/arel/engines/sql/primitives.rb --- lib/arel/algebra/relations/row.rb | 5 +++-- lib/arel/engines/memory/relations/array.rb | 4 ++++ lib/arel/engines/memory/relations/compound.rb | 2 +- lib/arel/engines/memory/relations/operations.rb | 4 ++-- lib/arel/engines/sql/engine.rb | 4 +++- lib/arel/engines/sql/primitives.rb | 4 ++++ lib/arel/engines/sql/relations/table.rb | 4 ++++ 7 files changed, 21 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/arel/algebra/relations/row.rb b/lib/arel/algebra/relations/row.rb index 3731dd9696..e8484944bd 100644 --- a/lib/arel/algebra/relations/row.rb +++ b/lib/arel/algebra/relations/row.rb @@ -4,12 +4,13 @@ module Arel deriving :==, :initialize def [](attribute) - tuple[relation.position_of(attribute)] + attribute.type_cast(tuple[relation.position_of(attribute)]) end def slice(*attributes) Row.new(relation, attributes.inject([]) do |cheese, attribute| - cheese << self[attribute] + # FIXME TESTME method chaining + cheese << tuple[relation.relation.position_of(attribute)] cheese end) end diff --git a/lib/arel/engines/memory/relations/array.rb b/lib/arel/engines/memory/relations/array.rb index 15a3e95e1b..6e2dc29252 100644 --- a/lib/arel/engines/memory/relations/array.rb +++ b/lib/arel/engines/memory/relations/array.rb @@ -14,6 +14,10 @@ module Arel end end + def format(attribute, value) + value + end + def eval @array.collect { |r| Row.new(self, r) } end diff --git a/lib/arel/engines/memory/relations/compound.rb b/lib/arel/engines/memory/relations/compound.rb index 3791fa4622..9e7827dfb3 100644 --- a/lib/arel/engines/memory/relations/compound.rb +++ b/lib/arel/engines/memory/relations/compound.rb @@ -3,7 +3,7 @@ module Arel delegate :array, :to => :relation def unoperated_rows - relation.eval.collect { |row| row.bind(self) } + relation.call.collect { |row| row.bind(self) } end end end diff --git a/lib/arel/engines/memory/relations/operations.rb b/lib/arel/engines/memory/relations/operations.rb index e35fbe3234..e0fd2824b3 100644 --- a/lib/arel/engines/memory/relations/operations.rb +++ b/lib/arel/engines/memory/relations/operations.rb @@ -47,8 +47,8 @@ module Arel class Join < Relation def eval result = [] - relation1.eval.each do |row1| - relation2.eval.each do |row2| + relation1.call.each do |row1| + relation2.call.each do |row2| combined_row = row1.combine(row2, self) if predicates.all? { |p| p.eval(combined_row) } result << combined_row diff --git a/lib/arel/engines/sql/engine.rb b/lib/arel/engines/sql/engine.rb index 0700ae9733..d27d93a5dc 100644 --- a/lib/arel/engines/sql/engine.rb +++ b/lib/arel/engines/sql/engine.rb @@ -20,7 +20,9 @@ module Arel def read(relation) # FIXME - class << rows = connection.execute(relation.to_sql) + rows = connection.select_rows(relation.to_sql) + + class << rows include Enumerable end diff --git a/lib/arel/engines/sql/primitives.rb b/lib/arel/engines/sql/primitives.rb index 9e9143ac0f..22ee19dcf0 100644 --- a/lib/arel/engines/sql/primitives.rb +++ b/lib/arel/engines/sql/primitives.rb @@ -4,6 +4,10 @@ module Arel original_relation.column_for(self) end + def type_cast(value) + root.relation.format(self, value) + end + def format(object) object.to_sql(Sql::Attribute.new(self)) end diff --git a/lib/arel/engines/sql/relations/table.rb b/lib/arel/engines/sql/relations/table.rb index 2653744149..e842f85ed1 100644 --- a/lib/arel/engines/sql/relations/table.rb +++ b/lib/arel/engines/sql/relations/table.rb @@ -16,6 +16,10 @@ module Arel end end + def format(attribute, value) + attribute.column.type_cast(value) + end + def column_for(attribute) has_attribute?(attribute) and columns.detect { |c| c.name == attribute.name.to_s } end -- cgit v1.2.3 From 44743bed5568b3065e4f9da7972e3ea1d0d9e728 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 16:14:28 -0400 Subject: joining across engines in either direction Conflicts: spec/arel/engines/memory/integration/joins/cross_engine_spec.rb --- lib/arel/algebra/relations/operations/join.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/arel/algebra/relations/operations/join.rb b/lib/arel/algebra/relations/operations/join.rb index 695f360b51..02a8fa629d 100644 --- a/lib/arel/algebra/relations/operations/join.rb +++ b/lib/arel/algebra/relations/operations/join.rb @@ -2,7 +2,7 @@ module Arel class Join < Relation attributes :relation1, :relation2, :predicates deriving :== - delegate :engine, :name, :to => :relation1 + delegate :name, :to => :relation1 hash_on :relation1 def initialize(relation1, relation2 = Nil.instance, *predicates) @@ -31,6 +31,10 @@ module Arel def join? true end + + def engine + relation1.engine != relation2.engine ? Memory::Engine.new : relation1.engine + end end class InnerJoin < Join; end @@ -39,6 +43,10 @@ module Arel def attributes relation1.externalize.attributes end + + def engine + relation1.engine + end end class Relation -- cgit v1.2.3 From dc7b51883b1cc8ad7e525b7315fb575ae77a5b3d Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 16:20:40 -0400 Subject: Whitespace --- lib/arel/algebra.rb | 2 +- lib/arel/algebra/extensions/array.rb | 4 ++-- lib/arel/algebra/extensions/class.rb | 10 +++++----- lib/arel/algebra/extensions/hash.rb | 2 +- lib/arel/algebra/extensions/pathname.rb | 2 +- lib/arel/algebra/extensions/symbol.rb | 2 +- lib/arel/algebra/predicates.rb | 2 +- lib/arel/algebra/primitives/attribute.rb | 8 ++++---- lib/arel/algebra/primitives/ordering.rb | 8 ++++---- lib/arel/algebra/relations.rb | 2 +- lib/arel/algebra/relations/operations/alias.rb | 2 +- lib/arel/algebra/relations/operations/group.rb | 2 +- lib/arel/algebra/relations/operations/join.rb | 4 ++-- lib/arel/algebra/relations/operations/order.rb | 4 ++-- lib/arel/algebra/relations/operations/skip.rb | 4 ++-- lib/arel/algebra/relations/operations/take.rb | 4 ++-- lib/arel/algebra/relations/row.rb | 10 +++++----- lib/arel/algebra/relations/utilities/compound.rb | 2 +- lib/arel/algebra/relations/writes.rb | 10 +++++----- lib/arel/engines.rb | 2 +- lib/arel/engines/memory.rb | 2 +- lib/arel/engines/memory/engine.rb | 4 ++-- lib/arel/engines/memory/primitives.rb | 10 +++++----- lib/arel/engines/memory/relations/array.rb | 6 +++--- lib/arel/engines/memory/relations/compound.rb | 2 +- lib/arel/engines/memory/relations/operations.rb | 16 ++++++++-------- lib/arel/engines/memory/relations/writes.rb | 4 ++-- lib/arel/engines/sql.rb | 2 +- lib/arel/engines/sql/christener.rb | 2 +- lib/arel/engines/sql/engine.rb | 6 +++--- lib/arel/engines/sql/extensions.rb | 2 +- lib/arel/engines/sql/extensions/array.rb | 2 +- lib/arel/engines/sql/extensions/nil_class.rb | 2 +- lib/arel/engines/sql/extensions/object.rb | 2 +- lib/arel/engines/sql/extensions/range.rb | 4 ++-- lib/arel/engines/sql/formatters.rb | 2 +- lib/arel/engines/sql/predicates.rb | 2 +- lib/arel/engines/sql/primitives.rb | 10 +++++----- lib/arel/engines/sql/relations.rb | 2 +- lib/arel/engines/sql/relations/operations/alias.rb | 2 +- lib/arel/engines/sql/relations/operations/join.rb | 2 +- lib/arel/engines/sql/relations/relation.rb | 2 +- lib/arel/engines/sql/relations/table.rb | 2 +- lib/arel/engines/sql/relations/utilities/compound.rb | 2 +- .../engines/sql/relations/utilities/externalization.rb | 2 +- lib/arel/engines/sql/relations/utilities/nil.rb | 2 +- lib/arel/engines/sql/relations/utilities/recursion.rb | 2 +- lib/arel/engines/sql/relations/writes.rb | 2 +- 48 files changed, 93 insertions(+), 93 deletions(-) (limited to 'lib') diff --git a/lib/arel/algebra.rb b/lib/arel/algebra.rb index f27882a343..c206fea0b0 100644 --- a/lib/arel/algebra.rb +++ b/lib/arel/algebra.rb @@ -1,4 +1,4 @@ require 'arel/algebra/extensions' require 'arel/algebra/predicates' require 'arel/algebra/relations' -require 'arel/algebra/primitives' \ No newline at end of file +require 'arel/algebra/primitives' diff --git a/lib/arel/algebra/extensions/array.rb b/lib/arel/algebra/extensions/array.rb index 935569a07b..48541a395e 100644 --- a/lib/arel/algebra/extensions/array.rb +++ b/lib/arel/algebra/extensions/array.rb @@ -2,11 +2,11 @@ class Array def to_hash Hash[*flatten] end - + def group_by inject({}) do |groups, element| (groups[yield(element)] ||= []) << element groups end end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/extensions/class.rb b/lib/arel/algebra/extensions/class.rb index f37898e7d7..0a729d8255 100644 --- a/lib/arel/algebra/extensions/class.rb +++ b/lib/arel/algebra/extensions/class.rb @@ -3,11 +3,11 @@ class Class @attributes = attrs attr_reader *attrs end - + def deriving(*methods) methods.each { |m| derive m } end - + def derive(method_name) methods = { :initialize => " @@ -24,14 +24,14 @@ class Class } class_eval methods[method_name], __FILE__, __LINE__ end - + def hash_on(delegatee) define_method :eql? do |other| self == other end - + define_method :hash do @hash ||= delegatee.hash end end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/extensions/hash.rb b/lib/arel/algebra/extensions/hash.rb index 7472b5aa73..82cd5e11d3 100644 --- a/lib/arel/algebra/extensions/hash.rb +++ b/lib/arel/algebra/extensions/hash.rb @@ -4,4 +4,4 @@ class Hash bound.merge(key.bind(relation) => value.bind(relation)) end end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/extensions/pathname.rb b/lib/arel/algebra/extensions/pathname.rb index 2f7e2733e7..45f1a5f6b3 100644 --- a/lib/arel/algebra/extensions/pathname.rb +++ b/lib/arel/algebra/extensions/pathname.rb @@ -2,4 +2,4 @@ class Pathname def /(path) (self + path).expand_path end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/extensions/symbol.rb b/lib/arel/algebra/extensions/symbol.rb index 787867bdc3..8d324a801c 100644 --- a/lib/arel/algebra/extensions/symbol.rb +++ b/lib/arel/algebra/extensions/symbol.rb @@ -2,4 +2,4 @@ class Symbol def to_attribute(relation) Arel::Attribute.new(relation, self) end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/predicates.rb b/lib/arel/algebra/predicates.rb index 7f093ded6d..72167c2b27 100644 --- a/lib/arel/algebra/predicates.rb +++ b/lib/arel/algebra/predicates.rb @@ -38,4 +38,4 @@ module Arel class LessThan < Binary; end class Match < Binary; end class In < Binary; end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/primitives/attribute.rb b/lib/arel/algebra/primitives/attribute.rb index aa1f2ae00c..44a2f41733 100644 --- a/lib/arel/algebra/primitives/attribute.rb +++ b/lib/arel/algebra/primitives/attribute.rb @@ -17,7 +17,7 @@ module Arel def aggregation? false end - + def inspect "" end @@ -133,16 +133,16 @@ module Arel end end include Expressions - + module Orderings def asc Ascending.new(self) end - + def desc Descending.new(self) end - + alias_method :to_ordering, :asc end include Orderings diff --git a/lib/arel/algebra/primitives/ordering.rb b/lib/arel/algebra/primitives/ordering.rb index e8d8f97188..a60d794f27 100644 --- a/lib/arel/algebra/primitives/ordering.rb +++ b/lib/arel/algebra/primitives/ordering.rb @@ -3,16 +3,16 @@ module Arel attributes :attribute deriving :initialize, :== delegate :relation, :to => :attribute - + def bind(relation) self.class.new(attribute.bind(relation)) end - + def to_ordering self end end - + class Ascending < Ordering; end class Descending < Ordering; end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/relations.rb b/lib/arel/algebra/relations.rb index 94df5938fe..f9fa24ba25 100644 --- a/lib/arel/algebra/relations.rb +++ b/lib/arel/algebra/relations.rb @@ -11,4 +11,4 @@ require 'arel/algebra/relations/operations/order' require 'arel/algebra/relations/operations/project' require 'arel/algebra/relations/operations/where' require 'arel/algebra/relations/operations/skip' -require 'arel/algebra/relations/operations/take' \ No newline at end of file +require 'arel/algebra/relations/operations/take' diff --git a/lib/arel/algebra/relations/operations/alias.rb b/lib/arel/algebra/relations/operations/alias.rb index 67837f6a75..0331d98b85 100644 --- a/lib/arel/algebra/relations/operations/alias.rb +++ b/lib/arel/algebra/relations/operations/alias.rb @@ -4,4 +4,4 @@ module Arel deriving :initialize alias_method :==, :equal? end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/relations/operations/group.rb b/lib/arel/algebra/relations/operations/group.rb index 879f2352c5..b8975ed3d6 100644 --- a/lib/arel/algebra/relations/operations/group.rb +++ b/lib/arel/algebra/relations/operations/group.rb @@ -13,4 +13,4 @@ module Arel true end end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/relations/operations/join.rb b/lib/arel/algebra/relations/operations/join.rb index 02a8fa629d..e47d9fa9e0 100644 --- a/lib/arel/algebra/relations/operations/join.rb +++ b/lib/arel/algebra/relations/operations/join.rb @@ -31,7 +31,7 @@ module Arel def join? true end - + def engine relation1.engine != relation2.engine ? Memory::Engine.new : relation1.engine end @@ -43,7 +43,7 @@ module Arel def attributes relation1.externalize.attributes end - + def engine relation1.engine end diff --git a/lib/arel/algebra/relations/operations/order.rb b/lib/arel/algebra/relations/operations/order.rb index 4e7133f5a8..a589b56997 100644 --- a/lib/arel/algebra/relations/operations/order.rb +++ b/lib/arel/algebra/relations/operations/order.rb @@ -2,7 +2,7 @@ module Arel class Order < Compound attributes :relation, :orderings deriving :== - + def initialize(relation, *orderings, &block) @relation = relation @orderings = (orderings + arguments_from_block(relation, &block)) \ @@ -15,4 +15,4 @@ module Arel (orderings + relation.orders).collect { |o| o.bind(self) }.collect { |o| o.to_ordering } end end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/relations/operations/skip.rb b/lib/arel/algebra/relations/operations/skip.rb index 930e4c94ea..2dda191c35 100644 --- a/lib/arel/algebra/relations/operations/skip.rb +++ b/lib/arel/algebra/relations/operations/skip.rb @@ -2,9 +2,9 @@ module Arel class Skip < Compound attributes :relation, :skipped deriving :initialize, :== - + def externalizable? true end end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/relations/operations/take.rb b/lib/arel/algebra/relations/operations/take.rb index 2fd3fdf635..eb32ec492e 100644 --- a/lib/arel/algebra/relations/operations/take.rb +++ b/lib/arel/algebra/relations/operations/take.rb @@ -2,9 +2,9 @@ module Arel class Take < Compound attributes :relation, :taken deriving :initialize, :== - + def externalizable? true end end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/relations/row.rb b/lib/arel/algebra/relations/row.rb index e8484944bd..3158557448 100644 --- a/lib/arel/algebra/relations/row.rb +++ b/lib/arel/algebra/relations/row.rb @@ -2,11 +2,11 @@ module Arel class Row attributes :relation, :tuple deriving :==, :initialize - + def [](attribute) attribute.type_cast(tuple[relation.position_of(attribute)]) end - + def slice(*attributes) Row.new(relation, attributes.inject([]) do |cheese, attribute| # FIXME TESTME method chaining @@ -14,13 +14,13 @@ module Arel cheese end) end - + def bind(relation) Row.new(relation, tuple) end - + def combine(other, relation) Row.new(relation, tuple + other.tuple) end end -end \ No newline at end of file +end diff --git a/lib/arel/algebra/relations/utilities/compound.rb b/lib/arel/algebra/relations/utilities/compound.rb index 99c3d02748..676d80a737 100644 --- a/lib/arel/algebra/relations/utilities/compound.rb +++ b/lib/arel/algebra/relations/utilities/compound.rb @@ -13,7 +13,7 @@ module Arel end OPERATION end - + private def arguments_from_block(relation, &block) block_given?? [yield(relation)] : [] diff --git a/lib/arel/algebra/relations/writes.rb b/lib/arel/algebra/relations/writes.rb index 352f7bc7e5..d344987915 100644 --- a/lib/arel/algebra/relations/writes.rb +++ b/lib/arel/algebra/relations/writes.rb @@ -2,7 +2,7 @@ module Arel class Deletion < Compound attributes :relation deriving :initialize, :== - + def call engine.delete(self) end @@ -15,7 +15,7 @@ module Arel def initialize(relation, record) @relation, @record = relation, record.bind(relation) end - + def call engine.create(self) end @@ -24,13 +24,13 @@ module Arel class Update < Compound attributes :relation, :assignments deriving :== - + def initialize(relation, assignments) @relation, @assignments = relation, assignments.bind(relation) end - + def call engine.update(self) end end -end \ No newline at end of file +end diff --git a/lib/arel/engines.rb b/lib/arel/engines.rb index 3f854edf90..cd848d83e2 100644 --- a/lib/arel/engines.rb +++ b/lib/arel/engines.rb @@ -1,2 +1,2 @@ require 'arel/engines/sql' -require 'arel/engines/memory' \ No newline at end of file +require 'arel/engines/memory' diff --git a/lib/arel/engines/memory.rb b/lib/arel/engines/memory.rb index df6f6f3d48..9e7193ef13 100644 --- a/lib/arel/engines/memory.rb +++ b/lib/arel/engines/memory.rb @@ -1,4 +1,4 @@ require 'arel/engines/memory/relations' require 'arel/engines/memory/primitives' require 'arel/engines/memory/engine' -require 'arel/engines/memory/predicates' \ No newline at end of file +require 'arel/engines/memory/predicates' diff --git a/lib/arel/engines/memory/engine.rb b/lib/arel/engines/memory/engine.rb index c8f79c9d57..c7ac9422d4 100644 --- a/lib/arel/engines/memory/engine.rb +++ b/lib/arel/engines/memory/engine.rb @@ -5,7 +5,7 @@ module Arel def read(relation) relation.eval end - + def create(relation) relation.eval end @@ -13,4 +13,4 @@ module Arel include CRUD end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/memory/primitives.rb b/lib/arel/engines/memory/primitives.rb index f8bbcedb55..935b34f5ee 100644 --- a/lib/arel/engines/memory/primitives.rb +++ b/lib/arel/engines/memory/primitives.rb @@ -4,24 +4,24 @@ module Arel row[self] end end - + class Value def eval(row) value end end - + class Ordering def eval(row1, row2) (attribute.eval(row1) <=> attribute.eval(row2)) * direction end end - + class Descending < Ordering def direction; -1 end end - + class Ascending < Ordering def direction; 1 end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/memory/relations/array.rb b/lib/arel/engines/memory/relations/array.rb index 6e2dc29252..5e7c0a4ab1 100644 --- a/lib/arel/engines/memory/relations/array.rb +++ b/lib/arel/engines/memory/relations/array.rb @@ -3,7 +3,7 @@ module Arel attributes :array, :attribute_names include Recursion::BaseCase deriving :==, :initialize - + def engine @engine ||= Memory::Engine.new end @@ -17,9 +17,9 @@ module Arel def format(attribute, value) value end - + def eval @array.collect { |r| Row.new(self, r) } end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/memory/relations/compound.rb b/lib/arel/engines/memory/relations/compound.rb index 9e7827dfb3..6dda92a6a1 100644 --- a/lib/arel/engines/memory/relations/compound.rb +++ b/lib/arel/engines/memory/relations/compound.rb @@ -1,7 +1,7 @@ module Arel class Compound < Relation delegate :array, :to => :relation - + def unoperated_rows relation.call.collect { |row| row.bind(self) } end diff --git a/lib/arel/engines/memory/relations/operations.rb b/lib/arel/engines/memory/relations/operations.rb index e0fd2824b3..8e01938360 100644 --- a/lib/arel/engines/memory/relations/operations.rb +++ b/lib/arel/engines/memory/relations/operations.rb @@ -4,7 +4,7 @@ module Arel unoperated_rows.select { |row| predicate.eval(row) } end end - + class Order < Compound def eval unoperated_rows.sort do |row1, row2| @@ -13,37 +13,37 @@ module Arel end end end - + class Project < Compound def eval unoperated_rows.collect { |r| r.slice(*projections) } end end - + class Take < Compound def eval unoperated_rows[0, taken] end end - + class Skip < Compound def eval unoperated_rows[skipped..-1] end end - + class Group < Compound def eval raise NotImplementedError end end - + class Alias < Compound def eval unoperated_rows end end - + class Join < Relation def eval result = [] @@ -58,4 +58,4 @@ module Arel result end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/memory/relations/writes.rb b/lib/arel/engines/memory/relations/writes.rb index fa8b84a32c..12c4f36c0d 100644 --- a/lib/arel/engines/memory/relations/writes.rb +++ b/lib/arel/engines/memory/relations/writes.rb @@ -1,7 +1,7 @@ module Arel class Insert < Compound def eval - unoperated_rows + [Row.new(self, record.values.collect(&:value))] + unoperated_rows + [Row.new(self, record.values.collect(&:value))] end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql.rb b/lib/arel/engines/sql.rb index aed1fd861e..f31cfc7dac 100644 --- a/lib/arel/engines/sql.rb +++ b/lib/arel/engines/sql.rb @@ -4,4 +4,4 @@ require 'arel/engines/sql/primitives' require 'arel/engines/sql/predicates' require 'arel/engines/sql/formatters' require 'arel/engines/sql/extensions' -require 'arel/engines/sql/christener' \ No newline at end of file +require 'arel/engines/sql/christener' diff --git a/lib/arel/engines/sql/christener.rb b/lib/arel/engines/sql/christener.rb index 5883a75f41..c1c9325208 100644 --- a/lib/arel/engines/sql/christener.rb +++ b/lib/arel/engines/sql/christener.rb @@ -10,4 +10,4 @@ module Arel end end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/engine.rb b/lib/arel/engines/sql/engine.rb index d27d93a5dc..5a8c9f16c5 100644 --- a/lib/arel/engines/sql/engine.rb +++ b/lib/arel/engines/sql/engine.rb @@ -21,11 +21,11 @@ module Arel def read(relation) # FIXME rows = connection.select_rows(relation.to_sql) - + class << rows include Enumerable end - + Array.new(rows, relation.attributes) end @@ -40,4 +40,4 @@ module Arel include CRUD end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/extensions.rb b/lib/arel/engines/sql/extensions.rb index 6f4ad32148..1ea31bc140 100644 --- a/lib/arel/engines/sql/extensions.rb +++ b/lib/arel/engines/sql/extensions.rb @@ -1,4 +1,4 @@ require 'arel/engines/sql/extensions/object' require 'arel/engines/sql/extensions/array' require 'arel/engines/sql/extensions/range' -require 'arel/engines/sql/extensions/nil_class' \ No newline at end of file +require 'arel/engines/sql/extensions/nil_class' diff --git a/lib/arel/engines/sql/extensions/array.rb b/lib/arel/engines/sql/extensions/array.rb index 1daa5abca7..d97dd1aa25 100644 --- a/lib/arel/engines/sql/extensions/array.rb +++ b/lib/arel/engines/sql/extensions/array.rb @@ -6,4 +6,4 @@ class Array def inclusion_predicate_sql "IN" end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/extensions/nil_class.rb b/lib/arel/engines/sql/extensions/nil_class.rb index 729c4cada7..6f38ecdf3a 100644 --- a/lib/arel/engines/sql/extensions/nil_class.rb +++ b/lib/arel/engines/sql/extensions/nil_class.rb @@ -2,4 +2,4 @@ class NilClass def equality_predicate_sql 'IS' end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/extensions/object.rb b/lib/arel/engines/sql/extensions/object.rb index ef990eee2f..65270ee3de 100644 --- a/lib/arel/engines/sql/extensions/object.rb +++ b/lib/arel/engines/sql/extensions/object.rb @@ -6,4 +6,4 @@ class Object def equality_predicate_sql '=' end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/extensions/range.rb b/lib/arel/engines/sql/extensions/range.rb index d7329efe34..946dbc2633 100644 --- a/lib/arel/engines/sql/extensions/range.rb +++ b/lib/arel/engines/sql/extensions/range.rb @@ -2,8 +2,8 @@ class Range def to_sql(formatter = nil) formatter.range self.begin, self.end end - + def inclusion_predicate_sql "BETWEEN" end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/formatters.rb b/lib/arel/engines/sql/formatters.rb index bc5f0f7c64..08a32843c9 100644 --- a/lib/arel/engines/sql/formatters.rb +++ b/lib/arel/engines/sql/formatters.rb @@ -47,7 +47,7 @@ module Arel class WhereClause < PassThrough end - class OrderClause < PassThrough + class OrderClause < PassThrough def ordering(ordering) "#{quote_table_name(name_for(ordering.attribute.original_relation))}.#{quote_column_name(ordering.attribute.name)} #{ordering.direction_sql}" end diff --git a/lib/arel/engines/sql/predicates.rb b/lib/arel/engines/sql/predicates.rb index dfeddb2de1..7e195c2605 100644 --- a/lib/arel/engines/sql/predicates.rb +++ b/lib/arel/engines/sql/predicates.rb @@ -34,4 +34,4 @@ module Arel class In < Binary def predicate_sql; operand2.inclusion_predicate_sql end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/primitives.rb b/lib/arel/engines/sql/primitives.rb index 22ee19dcf0..f2e8e8dabe 100644 --- a/lib/arel/engines/sql/primitives.rb +++ b/lib/arel/engines/sql/primitives.rb @@ -7,7 +7,7 @@ module Arel def type_cast(value) root.relation.format(self, value) end - + def format(object) object.to_sql(Sql::Attribute.new(self)) end @@ -28,17 +28,17 @@ module Arel object.to_sql(Sql::Value.new(relation)) end end - + class Ordering def to_sql(formatter = Sql::OrderClause.new(relation)) formatter.ordering self end end - + class Ascending < Ordering def direction_sql; 'ASC' end end - + class Descending < Ordering def direction_sql; 'DESC' end end @@ -72,4 +72,4 @@ module Arel class Average < Expression def function_sql; 'AVG' end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/relations.rb b/lib/arel/engines/sql/relations.rb index 0eb1303ec9..8360a1f806 100644 --- a/lib/arel/engines/sql/relations.rb +++ b/lib/arel/engines/sql/relations.rb @@ -6,4 +6,4 @@ require 'arel/engines/sql/relations/relation' require 'arel/engines/sql/relations/table' require 'arel/engines/sql/relations/operations/join' require 'arel/engines/sql/relations/operations/alias' -require 'arel/engines/sql/relations/writes' \ No newline at end of file +require 'arel/engines/sql/relations/writes' diff --git a/lib/arel/engines/sql/relations/operations/alias.rb b/lib/arel/engines/sql/relations/operations/alias.rb index 32c9911a69..9b6a484463 100644 --- a/lib/arel/engines/sql/relations/operations/alias.rb +++ b/lib/arel/engines/sql/relations/operations/alias.rb @@ -2,4 +2,4 @@ module Arel class Alias < Compound include Recursion::BaseCase end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/relations/operations/join.rb b/lib/arel/engines/sql/relations/operations/join.rb index f848fd3268..7c5e13510a 100644 --- a/lib/arel/engines/sql/relations/operations/join.rb +++ b/lib/arel/engines/sql/relations/operations/join.rb @@ -30,4 +30,4 @@ module Arel relation2 end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/relations/relation.rb b/lib/arel/engines/sql/relations/relation.rb index 5fd4121176..93c146352c 100644 --- a/lib/arel/engines/sql/relations/relation.rb +++ b/lib/arel/engines/sql/relations/relation.rb @@ -25,4 +25,4 @@ module Arel @christener ||= Sql::Christener.new end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/relations/table.rb b/lib/arel/engines/sql/relations/table.rb index e842f85ed1..0b6574eedc 100644 --- a/lib/arel/engines/sql/relations/table.rb +++ b/lib/arel/engines/sql/relations/table.rb @@ -19,7 +19,7 @@ module Arel def format(attribute, value) attribute.column.type_cast(value) end - + def column_for(attribute) has_attribute?(attribute) and columns.detect { |c| c.name == attribute.name.to_s } end diff --git a/lib/arel/engines/sql/relations/utilities/compound.rb b/lib/arel/engines/sql/relations/utilities/compound.rb index 61df196d6e..b63a829c67 100644 --- a/lib/arel/engines/sql/relations/utilities/compound.rb +++ b/lib/arel/engines/sql/relations/utilities/compound.rb @@ -3,4 +3,4 @@ module Arel delegate :table, :table_sql, :to => :relation end end - \ No newline at end of file + diff --git a/lib/arel/engines/sql/relations/utilities/externalization.rb b/lib/arel/engines/sql/relations/utilities/externalization.rb index 1ac6f2de8e..7f937e8423 100644 --- a/lib/arel/engines/sql/relations/utilities/externalization.rb +++ b/lib/arel/engines/sql/relations/utilities/externalization.rb @@ -11,4 +11,4 @@ module Arel relation.name + '_external' end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/relations/utilities/nil.rb b/lib/arel/engines/sql/relations/utilities/nil.rb index 77534b25ad..519ea8acf1 100644 --- a/lib/arel/engines/sql/relations/utilities/nil.rb +++ b/lib/arel/engines/sql/relations/utilities/nil.rb @@ -3,4 +3,4 @@ module Arel def table_sql(formatter = nil); '' end def name; '' end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/relations/utilities/recursion.rb b/lib/arel/engines/sql/relations/utilities/recursion.rb index 848b059507..84a526f57c 100644 --- a/lib/arel/engines/sql/relations/utilities/recursion.rb +++ b/lib/arel/engines/sql/relations/utilities/recursion.rb @@ -10,4 +10,4 @@ module Arel end end end -end \ No newline at end of file +end diff --git a/lib/arel/engines/sql/relations/writes.rb b/lib/arel/engines/sql/relations/writes.rb index edfd9f7233..4d753f5fca 100644 --- a/lib/arel/engines/sql/relations/writes.rb +++ b/lib/arel/engines/sql/relations/writes.rb @@ -33,4 +33,4 @@ module Arel ].join("\n") end end -end \ No newline at end of file +end -- cgit v1.2.3 From 0352d28a56de36946e691a0df390cfdfa7b1de7c Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 16:31:16 -0400 Subject: Moving a few stray SQL references in the memory engine code --- lib/arel/engines/memory/predicates.rb | 15 --------------- lib/arel/engines/sql/predicates.rb | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/lib/arel/engines/memory/predicates.rb b/lib/arel/engines/memory/predicates.rb index e233f3ba39..03d4f25b0a 100644 --- a/lib/arel/engines/memory/predicates.rb +++ b/lib/arel/engines/memory/predicates.rb @@ -1,25 +1,10 @@ module Arel - class Binary < Predicate def eval(row) operand1.eval(row).send(operator, operand2.eval(row)) end end - class CompoundPredicate < Binary - def to_sql(formatter = nil) - "(#{operand1.to_sql(formatter)} #{predicate_sql} #{operand2.to_sql(formatter)})" - end - end - - class Or < CompoundPredicate - def predicate_sql; "OR" end - end - - class And < CompoundPredicate - def predicate_sql; "AND" end - end - class Equality < Binary def operator; :== end end diff --git a/lib/arel/engines/sql/predicates.rb b/lib/arel/engines/sql/predicates.rb index 7e195c2605..b84c183c1d 100644 --- a/lib/arel/engines/sql/predicates.rb +++ b/lib/arel/engines/sql/predicates.rb @@ -5,6 +5,20 @@ module Arel end end + class CompoundPredicate < Binary + def to_sql(formatter = nil) + "(#{operand1.to_sql(formatter)} #{predicate_sql} #{operand2.to_sql(formatter)})" + end + end + + class Or < CompoundPredicate + def predicate_sql; "OR" end + end + + class And < CompoundPredicate + def predicate_sql; "AND" end + end + class Equality < Binary def predicate_sql operand2.equality_predicate_sql -- cgit v1.2.3 From ed8e0f9c02c291a51f93a2123e099d07756d75bb Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 16:42:17 -0400 Subject: Include modules to extend core classes to improve inspectability --- lib/arel/algebra/extensions/array.rb | 21 +++++---- lib/arel/algebra/extensions/class.rb | 65 +++++++++++++++------------- lib/arel/algebra/extensions/hash.rb | 12 +++-- lib/arel/algebra/extensions/object.rb | 31 +++++++------ lib/arel/algebra/extensions/pathname.rb | 12 +++-- lib/arel/algebra/extensions/symbol.rb | 10 +++-- lib/arel/engines/sql/extensions/array.rb | 19 +++++--- lib/arel/engines/sql/extensions/nil_class.rb | 12 +++-- lib/arel/engines/sql/extensions/object.rb | 18 +++++--- lib/arel/engines/sql/extensions/range.rb | 18 +++++--- 10 files changed, 134 insertions(+), 84 deletions(-) (limited to 'lib') diff --git a/lib/arel/algebra/extensions/array.rb b/lib/arel/algebra/extensions/array.rb index 48541a395e..e7e44ae909 100644 --- a/lib/arel/algebra/extensions/array.rb +++ b/lib/arel/algebra/extensions/array.rb @@ -1,12 +1,17 @@ -class Array - def to_hash - Hash[*flatten] - end +module Arel + module ArrayExtensions + def to_hash + Hash[*flatten] + end - def group_by - inject({}) do |groups, element| - (groups[yield(element)] ||= []) << element - groups + def group_by + inject({}) do |groups, element| + (groups[yield(element)] ||= []) << element + groups + end end + + Array.send(:include, self) end end + diff --git a/lib/arel/algebra/extensions/class.rb b/lib/arel/algebra/extensions/class.rb index 0a729d8255..d005814f91 100644 --- a/lib/arel/algebra/extensions/class.rb +++ b/lib/arel/algebra/extensions/class.rb @@ -1,37 +1,42 @@ -class Class - def attributes(*attrs) - @attributes = attrs - attr_reader *attrs - end - - def deriving(*methods) - methods.each { |m| derive m } - end +module Arel + module ClassExtensions + def attributes(*attrs) + @attributes = attrs + attr_reader *attrs + end - def derive(method_name) - methods = { - :initialize => " - def #{method_name}(#{@attributes.join(',')}) - #{@attributes.collect { |a| "@#{a} = #{a}" }.join("\n")} - end - ", - :== => " - def ==(other) - #{name} === other && - #{@attributes.collect { |a| "@#{a} == other.#{a}" }.join(" &&\n")} - end - " - } - class_eval methods[method_name], __FILE__, __LINE__ - end + def deriving(*methods) + methods.each { |m| derive m } + end - def hash_on(delegatee) - define_method :eql? do |other| - self == other + def derive(method_name) + methods = { + :initialize => " + def #{method_name}(#{@attributes.join(',')}) + #{@attributes.collect { |a| "@#{a} = #{a}" }.join("\n")} + end + ", + :== => " + def ==(other) + #{name} === other && + #{@attributes.collect { |a| "@#{a} == other.#{a}" }.join(" &&\n")} + end + " + } + class_eval methods[method_name], __FILE__, __LINE__ end - define_method :hash do - @hash ||= delegatee.hash + def hash_on(delegatee) + define_method :eql? do |other| + self == other + end + + define_method :hash do + @hash ||= delegatee.hash + end end + + Class.send(:include, self) end end + diff --git a/lib/arel/algebra/extensions/hash.rb b/lib/arel/algebra/extensions/hash.rb index 82cd5e11d3..05c15e7ebe 100644 --- a/lib/arel/algebra/extensions/hash.rb +++ b/lib/arel/algebra/extensions/hash.rb @@ -1,7 +1,11 @@ -class Hash - def bind(relation) - inject({}) do |bound, (key, value)| - bound.merge(key.bind(relation) => value.bind(relation)) +module Arel + module HashExtensions + def bind(relation) + inject({}) do |bound, (key, value)| + bound.merge(key.bind(relation) => value.bind(relation)) + end end + + Hash.send(:include, self) end end diff --git a/lib/arel/algebra/extensions/object.rb b/lib/arel/algebra/extensions/object.rb index efdbbf525f..80d68df177 100644 --- a/lib/arel/algebra/extensions/object.rb +++ b/lib/arel/algebra/extensions/object.rb @@ -1,20 +1,23 @@ -class Object - def bind(relation) - Arel::Value.new(self, relation) - end +module Arel + module ObjectExtensions + def bind(relation) + Arel::Value.new(self, relation) + end - def find_correlate_in(relation) - bind(relation) - end + def find_correlate_in(relation) + bind(relation) + end - def metaclass - class << self - self + def metaclass + class << self + self + end end - end - def let - yield(self) + def let + yield(self) + end + + Object.send(:include, self) end end - diff --git a/lib/arel/algebra/extensions/pathname.rb b/lib/arel/algebra/extensions/pathname.rb index 45f1a5f6b3..829f692d79 100644 --- a/lib/arel/algebra/extensions/pathname.rb +++ b/lib/arel/algebra/extensions/pathname.rb @@ -1,5 +1,9 @@ -class Pathname - def /(path) - (self + path).expand_path +module Arel + module PathnameExtensions + def /(path) + (self + path).expand_path + end + + Pathname.send(:include, self) end -end +end \ No newline at end of file diff --git a/lib/arel/algebra/extensions/symbol.rb b/lib/arel/algebra/extensions/symbol.rb index 8d324a801c..9bb47ef7ab 100644 --- a/lib/arel/algebra/extensions/symbol.rb +++ b/lib/arel/algebra/extensions/symbol.rb @@ -1,5 +1,9 @@ -class Symbol - def to_attribute(relation) - Arel::Attribute.new(relation, self) +module Arel + module SymbolExtensions + def to_attribute(relation) + Arel::Attribute.new(relation, self) + end + + Symbol.send(:include, self) end end diff --git a/lib/arel/engines/sql/extensions/array.rb b/lib/arel/engines/sql/extensions/array.rb index d97dd1aa25..7f15179721 100644 --- a/lib/arel/engines/sql/extensions/array.rb +++ b/lib/arel/engines/sql/extensions/array.rb @@ -1,9 +1,16 @@ -class Array - def to_sql(formatter = nil) - "(" + collect { |e| e.to_sql(formatter) }.join(', ') + ")" - end +module Arel + module Sql + module ArrayExtensions + def to_sql(formatter = nil) + "(" + collect { |e| e.to_sql(formatter) }.join(', ') + ")" + end - def inclusion_predicate_sql - "IN" + def inclusion_predicate_sql + "IN" + end + + Array.send(:include, self) + end end end + diff --git a/lib/arel/engines/sql/extensions/nil_class.rb b/lib/arel/engines/sql/extensions/nil_class.rb index 6f38ecdf3a..8c335f904a 100644 --- a/lib/arel/engines/sql/extensions/nil_class.rb +++ b/lib/arel/engines/sql/extensions/nil_class.rb @@ -1,5 +1,11 @@ -class NilClass - def equality_predicate_sql - 'IS' +module Arel + module Sql + module NilClassExtensions + def equality_predicate_sql + 'IS' + end + + NilClass.send(:include, self) + end end end diff --git a/lib/arel/engines/sql/extensions/object.rb b/lib/arel/engines/sql/extensions/object.rb index 65270ee3de..8fe63dba2f 100644 --- a/lib/arel/engines/sql/extensions/object.rb +++ b/lib/arel/engines/sql/extensions/object.rb @@ -1,9 +1,15 @@ -class Object - def to_sql(formatter) - formatter.scalar self - end +module Arel + module Sql + module ObjectExtensions + def to_sql(formatter) + formatter.scalar self + end - def equality_predicate_sql - '=' + def equality_predicate_sql + '=' + end + + Object.send(:include, self) + end end end diff --git a/lib/arel/engines/sql/extensions/range.rb b/lib/arel/engines/sql/extensions/range.rb index 946dbc2633..25bf1d01da 100644 --- a/lib/arel/engines/sql/extensions/range.rb +++ b/lib/arel/engines/sql/extensions/range.rb @@ -1,9 +1,15 @@ -class Range - def to_sql(formatter = nil) - formatter.range self.begin, self.end - end +module Arel + module Sql + module RangeExtensions + def to_sql(formatter = nil) + formatter.range self.begin, self.end + end - def inclusion_predicate_sql - "BETWEEN" + def inclusion_predicate_sql + "BETWEEN" + end + + Range.send(:include, self) + end end end -- cgit v1.2.3 From 605973614add20b504489e6fac086565717db14b Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 16:48:04 -0400 Subject: Removing unused array extensions --- lib/arel/algebra/extensions.rb | 1 - lib/arel/algebra/extensions/array.rb | 17 ----------------- 2 files changed, 18 deletions(-) delete mode 100644 lib/arel/algebra/extensions/array.rb (limited to 'lib') diff --git a/lib/arel/algebra/extensions.rb b/lib/arel/algebra/extensions.rb index 694dc60a2a..bc8edd3274 100644 --- a/lib/arel/algebra/extensions.rb +++ b/lib/arel/algebra/extensions.rb @@ -1,5 +1,4 @@ require 'arel/algebra/extensions/object' require 'arel/algebra/extensions/class' -require 'arel/algebra/extensions/array' require 'arel/algebra/extensions/symbol' require 'arel/algebra/extensions/hash' diff --git a/lib/arel/algebra/extensions/array.rb b/lib/arel/algebra/extensions/array.rb deleted file mode 100644 index e7e44ae909..0000000000 --- a/lib/arel/algebra/extensions/array.rb +++ /dev/null @@ -1,17 +0,0 @@ -module Arel - module ArrayExtensions - def to_hash - Hash[*flatten] - end - - def group_by - inject({}) do |groups, element| - (groups[yield(element)] ||= []) << element - groups - end - end - - Array.send(:include, self) - end -end - -- cgit v1.2.3 From 7fc820501ce7b997da43c47ec189aaa0d40645e1 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 16:49:15 -0400 Subject: Removing two unused externalizable? methods --- lib/arel/algebra/relations/operations/group.rb | 4 ---- lib/arel/algebra/relations/operations/skip.rb | 4 ---- 2 files changed, 8 deletions(-) (limited to 'lib') diff --git a/lib/arel/algebra/relations/operations/group.rb b/lib/arel/algebra/relations/operations/group.rb index b8975ed3d6..2bfc42214b 100644 --- a/lib/arel/algebra/relations/operations/group.rb +++ b/lib/arel/algebra/relations/operations/group.rb @@ -8,9 +8,5 @@ module Arel @groupings = (groupings + arguments_from_block(relation, &block)) \ .collect { |g| g.bind(relation) } end - - def externalizable? - true - end end end diff --git a/lib/arel/algebra/relations/operations/skip.rb b/lib/arel/algebra/relations/operations/skip.rb index 2dda191c35..689e06e1c3 100644 --- a/lib/arel/algebra/relations/operations/skip.rb +++ b/lib/arel/algebra/relations/operations/skip.rb @@ -2,9 +2,5 @@ module Arel class Skip < Compound attributes :relation, :skipped deriving :initialize, :== - - def externalizable? - true - end end end -- cgit v1.2.3 From 10c4b42c35f61145ac6ebb8d36f504344eef47cd Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 18:21:56 -0400 Subject: Fix bug in Order equality where Descending.new(attribute) was == Ascending.new(attribute) --- lib/arel/algebra/primitives/ordering.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/arel/algebra/primitives/ordering.rb b/lib/arel/algebra/primitives/ordering.rb index a60d794f27..3efb4c6280 100644 --- a/lib/arel/algebra/primitives/ordering.rb +++ b/lib/arel/algebra/primitives/ordering.rb @@ -1,7 +1,5 @@ module Arel class Ordering - attributes :attribute - deriving :initialize, :== delegate :relation, :to => :attribute def bind(relation) @@ -13,6 +11,13 @@ module Arel end end - class Ascending < Ordering; end - class Descending < Ordering; end + class Ascending < Ordering + attributes :attribute + deriving :initialize, :== + end + + class Descending < Ordering + attributes :attribute + deriving :initialize, :== + end end -- cgit v1.2.3 From a842aa572af1e8fac48f8a73a2e2985fbe39e046 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 18:35:45 -0400 Subject: Removing Object#metaclass definition (it's already in ActiveSupport) --- lib/arel/algebra/extensions/object.rb | 6 ------ 1 file changed, 6 deletions(-) (limited to 'lib') diff --git a/lib/arel/algebra/extensions/object.rb b/lib/arel/algebra/extensions/object.rb index 80d68df177..d8c60b5dd5 100644 --- a/lib/arel/algebra/extensions/object.rb +++ b/lib/arel/algebra/extensions/object.rb @@ -8,12 +8,6 @@ module Arel bind(relation) end - def metaclass - class << self - self - end - end - def let yield(self) end -- cgit v1.2.3 From 982f100d49095614df320d449f66f69aa827a763 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 18:40:24 -0400 Subject: Refactor #select_sql. Extract methods to generate clauses --- lib/arel/engines/sql/relations/relation.rb | 34 ++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/arel/engines/sql/relations/relation.rb b/lib/arel/engines/sql/relations/relation.rb index 93c146352c..c8a4d952fe 100644 --- a/lib/arel/engines/sql/relations/relation.rb +++ b/lib/arel/engines/sql/relations/relation.rb @@ -6,17 +6,18 @@ module Arel def select_sql [ - "SELECT #{attributes.collect { |a| a.to_sql(Sql::SelectClause.new(self)) }.join(', ')}", + "SELECT #{select_clauses.join(', ')}", "FROM #{table_sql(Sql::TableReference.new(self))}", - (joins(self) unless joins(self).blank? ), - ("WHERE #{wheres .collect { |w| w.to_sql(Sql::WhereClause.new(self)) }.join("\n\tAND ")}" unless wheres.blank? ), - ("GROUP BY #{groupings.collect { |g| g.to_sql(Sql::GroupClause.new(self)) }.join(', ')}" unless groupings.blank? ), - ("ORDER BY #{orders .collect { |o| o.to_sql(Sql::OrderClause.new(self)) }.join(', ')}" unless orders.blank? ), - ("LIMIT #{taken}" unless taken.blank? ), - ("OFFSET #{skipped}" unless skipped.blank? ) + (joins(self) unless joins(self).blank? ), + ("WHERE #{where_clauses.join("\n\tAND ")}" unless wheres.blank? ), + ("GROUP BY #{group_clauses.join(', ')}" unless groupings.blank? ), + ("ORDER BY #{order_clauses.join(', ')}" unless orders.blank? ), + ("LIMIT #{taken}" unless taken.blank? ), + ("OFFSET #{skipped}" unless skipped.blank? ) ].compact.join("\n") end + def inclusion_predicate_sql "IN" end @@ -24,5 +25,24 @@ module Arel def christener @christener ||= Sql::Christener.new end + + protected + + def select_clauses + attributes.collect { |a| a.to_sql(Sql::SelectClause.new(self)) } + end + + def where_clauses + wheres.collect { |w| w.to_sql(Sql::WhereClause.new(self)) } + end + + def group_clauses + groupings.collect { |g| g.to_sql(Sql::GroupClause.new(self)) } + end + + def order_clauses + orders.collect { |o| o.to_sql(Sql::OrderClause.new(self)) } + end + end end -- cgit v1.2.3 From 2e6fbf4f75c8e33380623b52e86ca8b90037712f Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sun, 17 May 2009 18:47:45 -0400 Subject: Extracting #build_query method for creating SQL from parts --- lib/arel/engines/sql/relations/relation.rb | 8 +++--- .../engines/sql/relations/utilities/compound.rb | 4 +++ lib/arel/engines/sql/relations/writes.rb | 29 ++++++++++++---------- 3 files changed, 25 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/arel/engines/sql/relations/relation.rb b/lib/arel/engines/sql/relations/relation.rb index c8a4d952fe..4cfb83a601 100644 --- a/lib/arel/engines/sql/relations/relation.rb +++ b/lib/arel/engines/sql/relations/relation.rb @@ -5,7 +5,7 @@ module Arel end def select_sql - [ + build_query \ "SELECT #{select_clauses.join(', ')}", "FROM #{table_sql(Sql::TableReference.new(self))}", (joins(self) unless joins(self).blank? ), @@ -14,10 +14,8 @@ module Arel ("ORDER BY #{order_clauses.join(', ')}" unless orders.blank? ), ("LIMIT #{taken}" unless taken.blank? ), ("OFFSET #{skipped}" unless skipped.blank? ) - ].compact.join("\n") end - def inclusion_predicate_sql "IN" end @@ -28,6 +26,10 @@ module Arel protected + def build_query(*parts) + parts.compact.join("\n") + end + def select_clauses attributes.collect { |a| a.to_sql(Sql::SelectClause.new(self)) } end diff --git a/lib/arel/engines/sql/relations/utilities/compound.rb b/lib/arel/engines/sql/relations/utilities/compound.rb index b63a829c67..f8ce4033fd 100644 --- a/lib/arel/engines/sql/relations/utilities/compound.rb +++ b/lib/arel/engines/sql/relations/utilities/compound.rb @@ -1,6 +1,10 @@ module Arel class Compound < Relation delegate :table, :table_sql, :to => :relation + + def build_query(*parts) + parts.compact.join("\n") + end end end diff --git a/lib/arel/engines/sql/relations/writes.rb b/lib/arel/engines/sql/relations/writes.rb index 4d753f5fca..f1a9bfd2ac 100644 --- a/lib/arel/engines/sql/relations/writes.rb +++ b/lib/arel/engines/sql/relations/writes.rb @@ -1,36 +1,39 @@ module Arel class Deletion < Compound def to_sql(formatter = nil) - [ + build_query \ "DELETE", "FROM #{table_sql}", - ("WHERE #{wheres.collect(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ), - ("LIMIT #{taken}" unless taken.blank? ), - ].compact.join("\n") + ("WHERE #{wheres.collect(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ), + ("LIMIT #{taken}" unless taken.blank? ) end end class Insert < Compound def to_sql(formatter = nil) - [ + build_query \ "INSERT", "INTO #{table_sql}", "(#{record.keys.collect { |key| engine.quote_column_name(key.name) }.join(', ')})", "VALUES (#{record.collect { |key, value| key.format(value) }.join(', ')})" - ].join("\n") end end class Update < Compound def to_sql(formatter = nil) - [ + build_query \ "UPDATE #{table_sql} SET", - assignments.collect do |attribute, value| - "#{engine.quote_column_name(attribute.name)} = #{attribute.format(value)}" - end.join(",\n"), - ("WHERE #{wheres.collect(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ), - ("LIMIT #{taken}" unless taken.blank? ) - ].join("\n") + assignment_sql, + ("WHERE #{wheres.collect(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ), + ("LIMIT #{taken}" unless taken.blank? ) + end + + protected + + def assignment_sql + assignments.collect do |attribute, value| + "#{engine.quote_column_name(attribute.name)} = #{attribute.format(value)}" + end.join(",\n") end end end -- cgit v1.2.3 From 1234c926cce2a979ec967a8c5bc6ba58cda1ce71 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 18 May 2009 00:59:08 -0400 Subject: Cleaning up Sql::Engine#read --- lib/arel/engines/sql/engine.rb | 6 ------ 1 file changed, 6 deletions(-) (limited to 'lib') diff --git a/lib/arel/engines/sql/engine.rb b/lib/arel/engines/sql/engine.rb index 5a8c9f16c5..7d2926040c 100644 --- a/lib/arel/engines/sql/engine.rb +++ b/lib/arel/engines/sql/engine.rb @@ -19,13 +19,7 @@ module Arel end def read(relation) - # FIXME rows = connection.select_rows(relation.to_sql) - - class << rows - include Enumerable - end - Array.new(rows, relation.attributes) end -- cgit v1.2.3 From 930c9f90a03729bdc380ab84882a118d8c17e54d Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 18 May 2009 01:11:40 -0400 Subject: Cleanup Sql formatters a bit --- lib/arel/engines/sql/formatters.rb | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/arel/engines/sql/formatters.rb b/lib/arel/engines/sql/formatters.rb index 08a32843c9..ae80feb18e 100644 --- a/lib/arel/engines/sql/formatters.rb +++ b/lib/arel/engines/sql/formatters.rb @@ -14,18 +14,17 @@ module Arel class SelectClause < Formatter def attribute(attribute) # FIXME this should check that the column exists - if attribute.name.to_s =~ /^\w*$/ - "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" + (attribute.alias ? " AS #{quote(attribute.alias.to_s)}" : "") - else - attribute.name.to_s + (attribute.alias ? " AS #{quote(attribute.alias.to_s)}" : "") - end + "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" + + (attribute.alias ? " AS #{quote(attribute.alias.to_s)}" : "") end def expression(expression) if expression.function_sql == "DISTINCT" - "#{expression.function_sql} #{expression.attribute.to_sql(self)}" + (expression.alias ? " AS #{quote_column_name(expression.alias)}" : '') + "#{expression.function_sql} #{expression.attribute.to_sql(self)}" + + (expression.alias ? " AS #{quote_column_name(expression.alias)}" : '') else - "#{expression.function_sql}(#{expression.attribute.to_sql(self)})" + (expression.alias ? " AS #{quote_column_name(expression.alias)}" : " AS #{expression.function_sql.to_s.downcase}_id") + "#{expression.function_sql}(#{expression.attribute.to_sql(self)})" + + (expression.alias ? " AS #{quote_column_name(expression.alias)}" : " AS #{expression.function_sql.to_s.downcase}_id") end end @@ -93,11 +92,8 @@ module Arel end def table(table) - if table.name =~ /^(\w|-)*$/ - quote_table_name(table.name) + (table.name != name_for(table) ? " AS " + quote_table_name(name_for(table)) : '') - else - table.name + (table.name != name_for(table) ? " AS " + (name_for(table)) : '') - end + quote_table_name(table.name) + + (table.name != name_for(table) ? " AS " + quote_table_name(name_for(table)) : '') end end @@ -106,10 +102,6 @@ module Arel quote(scalar, environment.column) end - def array(array) - "(" + array.collect { |e| e.to_sql(self) }.join(', ') + ")" - end - def range(left, right) "#{left} AND #{right}" end -- cgit v1.2.3 From 65e419c172217f9747e2e56b36fcc4b6089a0d6d Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 18 May 2009 01:25:09 -0400 Subject: Expand usages of #hash_on. The #hash definition it produces looks broken, but leaving it for now --- lib/arel/algebra/extensions/class.rb | 10 ---------- lib/arel/algebra/relations/operations/join.rb | 9 ++++++++- lib/arel/algebra/relations/utilities/compound.rb | 12 ++++++++++-- lib/arel/engines/sql/relations/table.rb | 9 ++++++++- 4 files changed, 26 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/arel/algebra/extensions/class.rb b/lib/arel/algebra/extensions/class.rb index d005814f91..520111b90f 100644 --- a/lib/arel/algebra/extensions/class.rb +++ b/lib/arel/algebra/extensions/class.rb @@ -25,16 +25,6 @@ module Arel } class_eval methods[method_name], __FILE__, __LINE__ end - - def hash_on(delegatee) - define_method :eql? do |other| - self == other - end - - define_method :hash do - @hash ||= delegatee.hash - end - end Class.send(:include, self) end diff --git a/lib/arel/algebra/relations/operations/join.rb b/lib/arel/algebra/relations/operations/join.rb index e47d9fa9e0..e9320f28e1 100644 --- a/lib/arel/algebra/relations/operations/join.rb +++ b/lib/arel/algebra/relations/operations/join.rb @@ -3,12 +3,19 @@ module Arel attributes :relation1, :relation2, :predicates deriving :== delegate :name, :to => :relation1 - hash_on :relation1 def initialize(relation1, relation2 = Nil.instance, *predicates) @relation1, @relation2, @predicates = relation1, relation2, predicates end + def hash + @hash ||= :relation1.hash + end + + def eql?(other) + self == other + end + def attributes @attributes ||= (relation1.externalize.attributes + relation2.externalize.attributes).collect { |a| a.bind(self) } diff --git a/lib/arel/algebra/relations/utilities/compound.rb b/lib/arel/algebra/relations/utilities/compound.rb index 676d80a737..5e775618f1 100644 --- a/lib/arel/algebra/relations/utilities/compound.rb +++ b/lib/arel/algebra/relations/utilities/compound.rb @@ -1,7 +1,6 @@ module Arel class Compound < Relation attr_reader :relation - hash_on :relation delegate :joins, :join?, :inserts, :taken, :skipped, :name, :externalizable?, :column_for, :engine, :to => :relation @@ -14,7 +13,16 @@ module Arel OPERATION end - private + def hash + @hash ||= :relation.hash + end + + def eql?(other) + self == other + end + + private + def arguments_from_block(relation, &block) block_given?? [yield(relation)] : [] end diff --git a/lib/arel/engines/sql/relations/table.rb b/lib/arel/engines/sql/relations/table.rb index 0b6574eedc..dd22f44226 100644 --- a/lib/arel/engines/sql/relations/table.rb +++ b/lib/arel/engines/sql/relations/table.rb @@ -4,7 +4,6 @@ module Arel cattr_accessor :engine attr_reader :name, :engine - hash_on :name def initialize(name, engine = Table.engine) @name, @engine = name.to_s, engine @@ -16,6 +15,14 @@ module Arel end end + def eql?(other) + self == other + end + + def hash + @hash ||= :name.hash + end + def format(attribute, value) attribute.column.type_cast(value) end -- cgit v1.2.3 From fbfbf1adcb2252c326aa869a6f94bd3269565ba2 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 18 May 2009 01:36:12 -0400 Subject: Removing unused Pathname extension --- lib/arel/algebra/extensions/pathname.rb | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 lib/arel/algebra/extensions/pathname.rb (limited to 'lib') diff --git a/lib/arel/algebra/extensions/pathname.rb b/lib/arel/algebra/extensions/pathname.rb deleted file mode 100644 index 829f692d79..0000000000 --- a/lib/arel/algebra/extensions/pathname.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Arel - module PathnameExtensions - def /(path) - (self + path).expand_path - end - - Pathname.send(:include, self) - end -end \ No newline at end of file -- cgit v1.2.3 From 082079169caab2a00f62d9de9c4bdb5dcbc591aa Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 18 May 2009 01:49:50 -0400 Subject: Better inspect output for Expressions --- lib/arel/algebra/primitives/expression.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/arel/algebra/primitives/expression.rb b/lib/arel/algebra/primitives/expression.rb index 5566e2d0b7..875498c282 100644 --- a/lib/arel/algebra/primitives/expression.rb +++ b/lib/arel/algebra/primitives/expression.rb @@ -13,6 +13,10 @@ module Arel true end + def inspect + "<#{self.class.name} #{attribute.inspect}>" + end + module Transformations def as(aliaz) self.class.new(attribute, aliaz, self) -- cgit v1.2.3 From 86364591af807ed3fa4a7304f53e6f3458cb4961 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Tue, 19 May 2009 21:36:34 -0400 Subject: Adding SqlLiteral with spec for counts --- lib/arel/engines/sql/primitives.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'lib') diff --git a/lib/arel/engines/sql/primitives.rb b/lib/arel/engines/sql/primitives.rb index f2e8e8dabe..bb3bed78e6 100644 --- a/lib/arel/engines/sql/primitives.rb +++ b/lib/arel/engines/sql/primitives.rb @@ -1,4 +1,14 @@ module Arel + class SqlLiteral < String + def relation + nil + end + + def to_sql(formatter = nil) + self + end + end + class Attribute def column original_relation.column_for(self) -- cgit v1.2.3