diff options
Diffstat (limited to 'lib/arel')
64 files changed, 0 insertions, 2501 deletions
diff --git a/lib/arel/algebra.rb b/lib/arel/algebra.rb deleted file mode 100644 index bc7b2fef2d..0000000000 --- a/lib/arel/algebra.rb +++ /dev/null @@ -1,10 +0,0 @@ -require 'arel/algebra/core_extensions' - -require 'arel/algebra/attributes' -require 'arel/algebra/header' -require 'arel/algebra/expression' -require 'arel/algebra/ordering' -require 'arel/algebra/predicates' -require 'arel/algebra/relations' -require 'arel/algebra/value' - diff --git a/lib/arel/algebra/attributes.rb b/lib/arel/algebra/attributes.rb deleted file mode 100644 index 6ce65fe132..0000000000 --- a/lib/arel/algebra/attributes.rb +++ /dev/null @@ -1,7 +0,0 @@ -require "arel/algebra/attributes/attribute" -require "arel/algebra/attributes/boolean" -require "arel/algebra/attributes/decimal" -require "arel/algebra/attributes/float" -require "arel/algebra/attributes/integer" -require "arel/algebra/attributes/string" -require "arel/algebra/attributes/time" diff --git a/lib/arel/algebra/attributes/attribute.rb b/lib/arel/algebra/attributes/attribute.rb deleted file mode 100644 index 16124abcc4..0000000000 --- a/lib/arel/algebra/attributes/attribute.rb +++ /dev/null @@ -1,304 +0,0 @@ -require 'set' - -module Arel - class TypecastError < StandardError ; end - class Attribute - attr_reader :relation, :name, :alias, :ancestor, :hash - attr_reader :history, :root - - def initialize(relation, name, options = {}) - @relation = relation # this is actually a table (I think) - @name = name - @alias = options[:alias] - @ancestor = options[:ancestor] - @history = [self] + (@ancestor ? @ancestor.history : []) - @root = @history.last - @original_relation = nil - @original_attribute = nil - - # FIXME: I think we can remove this eventually - @hash = name.hash + root.relation.class.hash - end - - def engine - @relation.engine - end - - def christener - @relation.christener - end - - def == other - super || - Attribute === other && - @name == other.name && - @alias == other.alias && - @ancestor == other.ancestor && - @relation == other.relation - end - - alias :eql? :== - - def named?(hypothetical_name) - (@alias || name).to_s == hypothetical_name.to_s - end - - def aggregation? - false - end - - def eval(row) - row[self] - 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(relation) - bind(relation) - 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 - - PREDICATES = [ - :eq, :eq_any, :eq_all, :not_eq, :not_eq_any, :not_eq_all, :lt, :lt_any, - :lt_all, :lteq, :lteq_any, :lteq_all, :gt, :gt_any, :gt_all, :gteq, - :gteq_any, :gteq_all, :matches, :matches_any, :matches_all, :not_matches, - :not_matches_any, :not_matches_all, :in, :in_any, :in_all, :not_in, - :not_in_any, :not_in_all - ] - - Predications = Class.new do - def self.instance_methods *args - warn "this module is deprecated, please use the PREDICATES constant" - PREDICATES - end - end - - def eq(other) - Predicates::Equality.new(self, other) - end - - def eq_any(*others) - Predicates::Any.build(Predicates::Equality, self, *others) - end - - def eq_all(*others) - Predicates::All.build(Predicates::Equality, self, *others) - end - - def not_eq(other) - Predicates::Inequality.new(self, other) - end - - def not_eq_any(*others) - Predicates::Any.build(Predicates::Inequality, self, *others) - end - - def not_eq_all(*others) - Predicates::All.build(Predicates::Inequality, self, *others) - end - - def lt(other) - Predicates::LessThan.new(self, other) - end - - def lt_any(*others) - Predicates::Any.build(Predicates::LessThan, self, *others) - end - - def lt_all(*others) - Predicates::All.build(Predicates::LessThan, self, *others) - end - - def lteq(other) - Predicates::LessThanOrEqualTo.new(self, other) - end - - def lteq_any(*others) - Predicates::Any.build(Predicates::LessThanOrEqualTo, self, *others) - end - - def lteq_all(*others) - Predicates::All.build(Predicates::LessThanOrEqualTo, self, *others) - end - - def gt(other) - Predicates::GreaterThan.new(self, other) - end - - def gt_any(*others) - Predicates::Any.build(Predicates::GreaterThan, self, *others) - end - - def gt_all(*others) - Predicates::All.build(Predicates::GreaterThan, self, *others) - end - - def gteq(other) - Predicates::GreaterThanOrEqualTo.new(self, other) - end - - def gteq_any(*others) - Predicates::Any.build(Predicates::GreaterThanOrEqualTo, self, *others) - end - - def gteq_all(*others) - Predicates::All.build(Predicates::GreaterThanOrEqualTo, self, *others) - end - - def matches(other) - Predicates::Match.new(self, other) - end - - def matches_any(*others) - Predicates::Any.build(Predicates::Match, self, *others) - end - - def matches_all(*others) - Predicates::All.build(Predicates::Match, self, *others) - end - - def not_matches(other) - Predicates::NotMatch.new(self, other) - end - - def not_matches_any(*others) - Predicates::Any.build(Predicates::NotMatch, self, *others) - end - - def not_matches_all(*others) - Predicates::All.build(Predicates::NotMatch, self, *others) - end - - def in(other) - Predicates::In.new(self, other) - end - - def in_any(*others) - Predicates::Any.build(Predicates::In, self, *others) - end - - def in_all(*others) - Predicates::All.build(Predicates::In, self, *others) - end - - def not_in(other) - Predicates::NotIn.new(self, other) - end - - def not_in_any(*others) - Predicates::Any.build(Predicates::NotIn, self, *others) - end - - def not_in_all(*others) - Predicates::All.build(Predicates::NotIn, self, *others) - end - - module Expressions - def count(distinct = false) - distinct ? Distinct.new(self).count : Count.new(self) - end - - def sum - Sum.new(self) - end - - def maximum - Maximum.new(self) - end - - def minimum - Minimum.new(self) - end - - def average - Average.new(self) - 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 - - module Types - def type_cast(value) - if root == self - raise NotImplementedError, "#type_cast should be implemented in a subclass." - else - root.type_cast(value) - end - end - - def type_cast_to_numeric(value, method) - return unless value - if value.respond_to?(:to_str) - str = value.to_str.strip - return if str.empty? - return $1.send(method) if str =~ /\A(-?(?:0|[1-9]\d*)(?:\.\d+)?|(?:\.\d+))\z/ - elsif value.respond_to?(method) - return value.send(method) - end - raise typecast_error(value) - end - - def typecast_error(value) - raise TypecastError, "could not typecast #{value.inspect} to #{self.class.name.split('::').last}" - end - end - include Types - - 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 diff --git a/lib/arel/algebra/attributes/boolean.rb b/lib/arel/algebra/attributes/boolean.rb deleted file mode 100644 index d69f2465df..0000000000 --- a/lib/arel/algebra/attributes/boolean.rb +++ /dev/null @@ -1,21 +0,0 @@ -module Arel - module Attributes - class Boolean < Attribute - def type_cast(value) - case value - when true, false then value - # when nil then options[:allow_nil] ? nil : false - when nil then false - when 1 then true - when 0 then false - else - case value.to_s.downcase.strip - when 'true' then true - when 'false' then false - else raise typecast_error(value) - end - end - end - end - end -end diff --git a/lib/arel/algebra/attributes/decimal.rb b/lib/arel/algebra/attributes/decimal.rb deleted file mode 100644 index bf6587fa34..0000000000 --- a/lib/arel/algebra/attributes/decimal.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Arel - module Attributes - class Decimal < Attribute - def type_cast(val) - type_cast_to_numeric(val, :to_d) - end - end - end -end diff --git a/lib/arel/algebra/attributes/float.rb b/lib/arel/algebra/attributes/float.rb deleted file mode 100644 index 01c95e69f9..0000000000 --- a/lib/arel/algebra/attributes/float.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Arel - module Attributes - class Float < Attribute - def type_cast(val) - type_cast_to_numeric(val, :to_f) - end - end - end -end diff --git a/lib/arel/algebra/attributes/integer.rb b/lib/arel/algebra/attributes/integer.rb deleted file mode 100644 index 8d4f572989..0000000000 --- a/lib/arel/algebra/attributes/integer.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Arel - module Attributes - class Integer < Attribute - def type_cast(val) - type_cast_to_numeric(val, :to_i) - end - end - end -end - diff --git a/lib/arel/algebra/attributes/string.rb b/lib/arel/algebra/attributes/string.rb deleted file mode 100644 index 5ea91a59d8..0000000000 --- a/lib/arel/algebra/attributes/string.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Arel - module Attributes - class String < Attribute - def type_cast(value) - return unless value - value.to_s - end - end - end -end diff --git a/lib/arel/algebra/attributes/time.rb b/lib/arel/algebra/attributes/time.rb deleted file mode 100644 index 7a2de726c8..0000000000 --- a/lib/arel/algebra/attributes/time.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Arel - module Attributes - class Time < Attribute - end - end -end diff --git a/lib/arel/algebra/core_extensions.rb b/lib/arel/algebra/core_extensions.rb deleted file mode 100644 index 4416ff6b77..0000000000 --- a/lib/arel/algebra/core_extensions.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'arel/algebra/core_extensions/object' -require 'arel/algebra/core_extensions/symbol' -require 'arel/algebra/core_extensions/hash' diff --git a/lib/arel/algebra/core_extensions/hash.rb b/lib/arel/algebra/core_extensions/hash.rb deleted file mode 100644 index 4b36a3e2bc..0000000000 --- a/lib/arel/algebra/core_extensions/hash.rb +++ /dev/null @@ -1,7 +0,0 @@ -class Hash - def bind(relation) - Hash[map { |key, value| - [key.bind(relation), value.bind(relation)] - }] - end -end diff --git a/lib/arel/algebra/core_extensions/object.rb b/lib/arel/algebra/core_extensions/object.rb deleted file mode 100644 index 2dc5ea2677..0000000000 --- a/lib/arel/algebra/core_extensions/object.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Arel - module ObjectExtensions - def bind(relation) - Arel::Value.new(self, relation) - end - - def find_correlate_in(relation) - bind(relation) - end - - Object.send(:include, self) - end -end diff --git a/lib/arel/algebra/core_extensions/symbol.rb b/lib/arel/algebra/core_extensions/symbol.rb deleted file mode 100644 index f575ad533a..0000000000 --- a/lib/arel/algebra/core_extensions/symbol.rb +++ /dev/null @@ -1,9 +0,0 @@ -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/algebra/expression.rb b/lib/arel/algebra/expression.rb deleted file mode 100644 index 32cf4f12c9..0000000000 --- a/lib/arel/algebra/expression.rb +++ /dev/null @@ -1,56 +0,0 @@ -module Arel - class Expression < Attribute - attr_reader :attribute - alias :name :alias - - def initialize(attribute, aliaz = nil, ancestor = nil) - super(attribute.relation, aliaz, :alias => aliaz, :ancestor => ancestor) - @attribute = attribute - end - - def aggregation? - true - end - - def to_sql(formatter = Sql::SelectClause.new(relation)) - formatter.expression self - end - - def as(aliaz) - self.class.new(attribute, aliaz, self) - end - - def bind(new_relation) - new_relation == relation ? self : self.class.new(attribute.bind(new_relation), @alias, self) - end - - def to_attribute(relation) - Attribute.new(relation, @alias, :ancestor => 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 - diff --git a/lib/arel/algebra/header.rb b/lib/arel/algebra/header.rb deleted file mode 100644 index dc779d53c3..0000000000 --- a/lib/arel/algebra/header.rb +++ /dev/null @@ -1,66 +0,0 @@ -module Arel - class Header - include Enumerable - - def initialize(attrs = []) - @attributes = attrs.to_ary - @names = {} - end - - def each - to_ary.each { |e| yield e } - self - end - - def [](key) - case key - when String, Symbol then find_by_name(key) - when Attribute then find_by_attribute(key) - end - end - - def ==(other) - to_set == other.to_set - end - - def union(other) - new(to_ary | other) - end - - alias | union - - def to_ary - @attributes - end - - def bind(relation) - Header.new(map { |a| a.bind(relation) }) - end - - # TMP - def index(i) - to_ary.index(i) - end - - private - - def new(attrs) - self.class.new(attrs) - end - - def matching(attribute) - select { |a| !a.is_a?(Value) && a.root == attribute.root } - end - - def find_by_name(name) - k = name.to_sym - @names[k] ||= @attributes.detect { |a| a.named?(k) } - end - - def find_by_attribute(attr) - matching(attr).max do |a, b| - (a.original_attribute / attr) <=> (b.original_attribute / attr) - end - end - end -end diff --git a/lib/arel/algebra/ordering.rb b/lib/arel/algebra/ordering.rb deleted file mode 100644 index c1a4ef8b70..0000000000 --- a/lib/arel/algebra/ordering.rb +++ /dev/null @@ -1,31 +0,0 @@ -module Arel - class Ordering < Struct.new(:attribute) - delegate :relation, :to => :attribute - - def bind(relation) - self.class.new(attribute.bind(relation)) - end - - def to_ordering - self - end - - def eval(row1, row2) - (attribute.eval(row1) <=> attribute.eval(row2)) * direction - end - - def to_sql(formatter = Sql::OrderClause.new(relation)) - formatter.ordering self - end - end - - class Ascending < Ordering - def direction; 1 end - def direction_sql; 'ASC' end - end - - class Descending < Ordering - def direction_sql; 'DESC' end - def direction; -1 end - end -end diff --git a/lib/arel/algebra/predicates.rb b/lib/arel/algebra/predicates.rb deleted file mode 100644 index 2426aae396..0000000000 --- a/lib/arel/algebra/predicates.rb +++ /dev/null @@ -1,306 +0,0 @@ -module Arel - module Predicates - class Predicate - def or(other_predicate) - Or.new(self, other_predicate) - end - - def and(other_predicate) - And.new(self, other_predicate) - end - - def complement - Not.new(self) - end - - def not - self.complement - end - end - - class Polyadic < Predicate - attr_reader :predicates - - def initialize(*predicates) - @predicates = predicates - end - - # Build a Polyadic predicate based on: - # * <tt>operator</tt> - The Predicate subclass that defines the type of operation - # (LessThan, Equality, etc) - # * <tt>operand1</tt> - The left-hand operand (normally an Arel::Attribute) - # * <tt>additional_operands</tt> - All possible right-hand operands - def self.build(operator, operand1, *additional_operands) - new( - *additional_operands.uniq.map do |operand| - operator.new(operand1, operand) - end - ) - end - - def ==(other) - super || predicates == other.predicates - end - - def bind(relation) - self.class.new( - *predicates.map {|p| p.find_correlate_in(relation)} - ) - end - - def eval(row) - predicates.send(compounder) do |operation| - operation.eval(row) - end - end - - def to_sql(formatter = nil) - "(" + - predicates.map {|p| p.to_sql(formatter)}.join(" #{predicate_sql} ") + - ")" - end - end - - class Any < Polyadic - def complement - All.new(*predicates.map {|p| p.complement}) - end - - def compounder; :any? end - - def predicate_sql; "OR" end - end - - class All < Polyadic - def complement - Any.new(*predicates.map {|p| p.complement}) - end - - def compounder; :all? end - - def predicate_sql; "AND" end - end - - class Unary < Predicate - attr_reader :operand - - def initialize operand - @operand = operand - end - - def bind(relation) - self.class.new(operand.find_correlate_in(relation)) - end - - def == other - super || self.class === other && operand == other.operand - end - - def eval(row) - operand.eval(row).send(operator) - end - - def to_sql(formatter = nil) - "#{predicate_sql} (#{operand.to_sql(formatter)})" - end - end - - class Not < Unary - def complement - operand - end - - def eval(row) - !operand.eval(row) - end - - def predicate_sql; "NOT" end - end - - class Binary < Unary - attr_reader :operand2 - alias :operand1 :operand - - def initialize left, right - super(left) - @operand2 = right - end - - def ==(other) - super && @operand2 == other.operand2 - end - - def bind(relation) - self.class.new(operand1.find_correlate_in(relation), operand2.find_correlate_in(relation)) - end - - def eval(row) - operand1.eval(row).send(operator, operand2.eval(row)) - end - - def to_sql(formatter = nil) - "#{operand1.to_sql} #{predicate_sql} #{operand1.format(operand2)}" - end - alias :value :to_sql - end - - class CompoundPredicate < Binary - def eval(row) - eval "operand1.eval(row) #{operator} operand2.eval(row)" - end - - def to_sql(formatter = nil) - "(#{operand1.to_sql(formatter)} #{predicate_sql} #{operand2.to_sql(formatter)})" - end - end - - class And < CompoundPredicate - def complement - Or.new(operand1.complement, operand2.complement) - end - - def operator; :and end - - def predicate_sql; "AND" end - end - - class Or < CompoundPredicate - def complement - And.new(operand1.complement, operand2.complement) - end - - def operator; :or end - - def predicate_sql; "OR" end - end - - class Equality < Binary - def ==(other) - self.class === other and - ((operand1 == other.operand1 and operand2 == other.operand2) or - (operand1 == other.operand2 and operand2 == other.operand1)) - end - - def complement - Inequality.new(operand1, operand2) - end - - def operator; :== end - - def predicate_sql - operand2.equality_predicate_sql - end - end - - class Inequality < Equality - def complement - Equality.new(operand1, operand2) - end - - def operator; :"!=" end - def eval(row) - operand1.eval(row) != operand2.eval(row) - end - - def predicate_sql - operand2.inequality_predicate_sql - end - end - - class GreaterThanOrEqualTo < Binary - def complement - LessThan.new(operand1, operand2) - end - - def operator; :>= end - - def predicate_sql; '>=' end - end - - class GreaterThan < Binary - def complement - LessThanOrEqualTo.new(operand1, operand2) - end - - def operator; :> end - - def predicate_sql; '>' end - end - - class LessThanOrEqualTo < Binary - def complement - GreaterThan.new(operand1, operand2) - end - - def operator; :<= end - - def predicate_sql; '<=' end - end - - class LessThan < Binary - def complement - GreaterThanOrEqualTo.new(operand1, operand2) - end - - def operator; :< end - - def predicate_sql; '<' end - end - - class Match < Binary - def complement - NotMatch.new(operand1, operand2) - end - - def operator; :=~ end - - def predicate_sql; 'LIKE' end - end - - class NotMatch < Binary - def complement - Match.new(operand1, operand2) - end - - def eval(row) - operand1.eval(row) !~ operand2.eval(row) - end - - def predicate_sql; 'NOT LIKE' end - end - - class In < Binary - def complement - NotIn.new(operand1, operand2) - end - - def eval(row) - operand2.eval(row).include?(operand1.eval(row)) - end - - def to_sql(formatter = nil) - if operand2.is_a?(Range) && operand2.exclude_end? - GreaterThanOrEqualTo.new(operand1, operand2.begin).and( - LessThan.new(operand1, operand2.end) - ).to_sql(formatter) - else - super - end - end - - def predicate_sql; operand2.inclusion_predicate_sql end - end - - class NotIn < Binary - def complement - In.new(operand1, operand2) - end - - def eval(row) - !(operand2.eval(row).include?(operand1.eval(row))) - end - - def predicate_sql; operand2.exclusion_predicate_sql end - end - end -end diff --git a/lib/arel/algebra/relations.rb b/lib/arel/algebra/relations.rb deleted file mode 100644 index 9f438615cd..0000000000 --- a/lib/arel/algebra/relations.rb +++ /dev/null @@ -1,16 +0,0 @@ -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/from' -require 'arel/algebra/relations/operations/group' -require 'arel/algebra/relations/operations/having' -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' -require 'arel/algebra/relations/operations/lock' diff --git a/lib/arel/algebra/relations/operations/from.rb b/lib/arel/algebra/relations/operations/from.rb deleted file mode 100644 index 3ebfb10cb2..0000000000 --- a/lib/arel/algebra/relations/operations/from.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Arel - class From < Compound - attr_reader :sources - - def initialize relation, sources - super(relation) - @sources = sources - end - - def eval - unoperated_rows[sources..-1] - end - end -end diff --git a/lib/arel/algebra/relations/operations/group.rb b/lib/arel/algebra/relations/operations/group.rb deleted file mode 100644 index 16a2963c93..0000000000 --- a/lib/arel/algebra/relations/operations/group.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Arel - class Group < Compound - attr_reader :groupings - - def initialize(relation, groupings) - super(relation) - @groupings = groupings.collect { |g| g.bind(relation) } - end - - def eval - raise NotImplementedError - end - end -end diff --git a/lib/arel/algebra/relations/operations/having.rb b/lib/arel/algebra/relations/operations/having.rb deleted file mode 100644 index 3d8115c2f6..0000000000 --- a/lib/arel/algebra/relations/operations/having.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Arel - class Having < Compound - attr_reader :predicates - - def initialize(relation, predicates) - super(relation) - @predicates = predicates.map { |p| p.bind(relation) } - end - - def havings - @havings ||= relation.havings + predicates - end - end -end diff --git a/lib/arel/algebra/relations/operations/join.rb b/lib/arel/algebra/relations/operations/join.rb deleted file mode 100644 index 35374972be..0000000000 --- a/lib/arel/algebra/relations/operations/join.rb +++ /dev/null @@ -1,103 +0,0 @@ -module Arel - class Join - include Relation - - attr_reader :relation1, :relation2, :predicates - - def initialize(relation1, relation2 = Nil.instance, *predicates) - @relation1 = relation1 - @relation2 = relation2 - @predicates = predicates - @attributes = nil - end - - def name - relation1.name - end - - def attributes - @attributes ||= (relation1.externalize.attributes | relation2.externalize.attributes).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 - - def engine - relation1.engine != relation2.engine ? Memory::Engine.new : relation1.engine - 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.relation).to_sql(Sql::WhereClause.new(environment)) }.join(' AND ') - ].compact.join(" ") - [relation1.joins(environment), this_join, relation2.joins(environment)].compact.join(" ") - end - end - - def eval - result = [] - 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 - end - end - end - result - end - - def to_sql(formatter = nil) - compiler.select_sql - end - end - - class InnerJoin < Join - def join_sql; "INNER JOIN" end - end - - class OuterJoin < Join - def join_sql; "LEFT OUTER JOIN" end - end - - class StringJoin < Join - def joins(environment, formatter = Sql::TableReference.new(environment)) - [relation1.joins(environment), relation2].compact.join(" ") - end - - def externalizable? - relation1.externalizable? - end - - def attributes - relation1.externalize.attributes - end - - def engine - relation1.engine - end - end -end diff --git a/lib/arel/algebra/relations/operations/lock.rb b/lib/arel/algebra/relations/operations/lock.rb deleted file mode 100644 index 394ad6f0ec..0000000000 --- a/lib/arel/algebra/relations/operations/lock.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Arel - class Lock < Compound - attr_reader :locked - - def initialize(relation, locked) - super(relation) - @locked = true == locked ? " FOR UPDATE" : locked - end - end -end diff --git a/lib/arel/algebra/relations/operations/order.rb b/lib/arel/algebra/relations/operations/order.rb deleted file mode 100644 index e7306fe384..0000000000 --- a/lib/arel/algebra/relations/operations/order.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Arel - class Order < Compound - attr_reader :orderings - - def initialize(relation, orderings) - super(relation) - @orderings = orderings.collect { |o| o.bind(relation) } - end - - # TESTME - def orders - # QUESTION - do we still need relation.orders ? - (orderings + relation.orders).collect { |o| o.bind(self) }.collect { |o| o.to_ordering } - end - - def eval - unoperated_rows.sort do |row1, row2| - ordering = orders.detect { |o| o.eval(row1, row2) != 0 } || orders.last - ordering.eval(row1, row2) - end - end - end -end diff --git a/lib/arel/algebra/relations/operations/project.rb b/lib/arel/algebra/relations/operations/project.rb deleted file mode 100644 index 1c24ae6caf..0000000000 --- a/lib/arel/algebra/relations/operations/project.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Arel - class Project < Compound - attr_reader :projections, :attributes, :christener - - def initialize(relation, projections) - super(relation) - @projections = projections.map { |p| p.bind(relation) } - @christener = Sql::Christener.new - @attributes = Header.new(projections.map { |x| x.bind(self) }) - end - - def externalizable? - attributes.any? { |a| a.respond_to?(:aggregation?) && a.aggregation? } || relation.externalizable? - end - - def eval - unoperated_rows.collect { |r| r.slice(*projections) } - end - end -end diff --git a/lib/arel/algebra/relations/operations/skip.rb b/lib/arel/algebra/relations/operations/skip.rb deleted file mode 100644 index a9157e914c..0000000000 --- a/lib/arel/algebra/relations/operations/skip.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Arel - class Skip < Compound - attr_reader :relation, :skipped - - def initialize relation, skipped - super(relation) - @skipped = skipped - end - - def eval - unoperated_rows[skipped..-1] - end - end -end diff --git a/lib/arel/algebra/relations/operations/take.rb b/lib/arel/algebra/relations/operations/take.rb deleted file mode 100644 index 299c29ab72..0000000000 --- a/lib/arel/algebra/relations/operations/take.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Arel - class Take < Compound - attr_reader :taken - - def initialize relation, taken - super(relation) - @taken = taken - end - - def externalizable? - true - end - - def eval - unoperated_rows[0, taken] - end - end -end diff --git a/lib/arel/algebra/relations/operations/where.rb b/lib/arel/algebra/relations/operations/where.rb deleted file mode 100644 index ed80fd93ba..0000000000 --- a/lib/arel/algebra/relations/operations/where.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Arel - class Where < Compound - attr_reader :predicates - - def initialize(relation, predicates) - super(relation) - @predicates = predicates.map { |p| p.bind(relation) } - @wheres = nil - end - - def wheres - @wheres ||= relation.wheres + predicates - end - - def eval - unoperated_rows.select { |row| predicates.all? { |p| p.eval(row) } } - end - - def to_sql(formatter = nil) - compiler.select_sql - end - end -end diff --git a/lib/arel/algebra/relations/relation.rb b/lib/arel/algebra/relations/relation.rb deleted file mode 100644 index 765d6fe930..0000000000 --- a/lib/arel/algebra/relations/relation.rb +++ /dev/null @@ -1,205 +0,0 @@ -module Arel - module Relation - include Enumerable - - @@connection_tables_primary_keys = {} - - attr_reader :count - - def session - Session.instance - end - - def join? - false - end - - def call - engine.read(self) - end - - def bind(relation) - self - end - - def externalize - @externalized ||= externalizable?? Externalization.new(self) : self - end - - def externalizable? - false - end - - def compiler - @compiler ||= begin - Arel::SqlCompiler.const_get("#{engine.adapter_name}Compiler").new(self) - rescue - Arel::SqlCompiler::GenericCompiler.new(self) - end - end - - def to_sql(formatter = nil) - sql = compiler.select_sql - - return sql unless formatter - formatter.select sql, self - end - - def christener - @christener ||= Sql::Christener.new - end - - def inclusion_predicate_sql - "IN" - end - - def exclusion_predicate_sql - "NOT IN" - end - - def primary_key - connection_id = engine.connection.object_id - if @@connection_tables_primary_keys[connection_id] && @@connection_tables_primary_keys[connection_id].has_key?(table.name) - @@connection_tables_primary_keys[connection_id][table.name] - else - @@connection_tables_primary_keys[connection_id] ||= {} - @@connection_tables_primary_keys[connection_id][table.name] = engine.connection.primary_key(table.name) - end - end - - def select_clauses - attributes.map { |a| - case a - when Value - a.value - else - a.to_sql(Sql::SelectClause.new(self)) - end - } - end - - def from_clauses - sources.empty? ? table_sql : sources - end - - def where_clauses - wheres.map { |w| w.value } - end - - def group_clauses - groupings.collect { |g| g.to_sql(Sql::GroupClause.new(self)) } - end - - def having_clauses - havings.collect { |g| g.to_sql(Sql::HavingClause.new(self)) } - end - - def order_clauses - orders.collect { |o| o.to_sql(Sql::OrderClause.new(self)) } - end - - def each - session.read(self).each { |e| yield e } - end - - def join(other_relation = nil, join_class = InnerJoin) - case other_relation - when String - StringJoin.new(self, other_relation) - when Relation - JoinOperation.new(join_class, self, other_relation) - else - self - end - end - - def outer_join(other_relation = nil) - join(other_relation, OuterJoin) - end - - %w{ - having group order - }.each do |op| - class_eval <<-OPERATION, __FILE__, __LINE__ - def #{op}(*args) - args.all? { |x| x.blank? } ? self : #{op.capitalize}.new(self, args) - end - OPERATION - end - - def project *args - args.empty? ? self : Project.new(self, args) - end - - def where clause = nil - clause ? Where.new(self, Array(clause)) : self - end - - def skip thing = nil - thing ? Skip.new(self, thing) : self - end - - def take count - Take.new self, count - end - - def from thing - From.new self, thing - end - - def lock(locking = true) - Lock.new(self, locking) - end - - def alias - Alias.new(self) - end - - def insert(record) - session.create Insert.new(self, record) - end - - def update(assignments) - session.update Update.new(self, assignments) - end - - def delete - session.delete Deletion.new(self) - end - - JoinOperation = Struct.new(:join_class, :relation1, :relation2) do - def on(*predicates) - join_class.new(relation1, relation2, *predicates) - end - end - - def [](index) - attributes[index] - end - - def find_attribute_matching_name(name) - attributes.detect { |a| a.named?(name) } || Attribute.new(self, name) - end - - def position_of(attribute) - @position_of ||= {} - - return @position_of[attribute] if @position_of.key? attribute - - @position_of[attribute] = attributes.index(attributes[attribute]) - end - - def attributes; Header.new end - def projections; [] end - def wheres; [] end - def orders; [] end - def inserts; [] end - def groupings; [] end - def havings; [] end - def joins(formatter = nil); nil end # FIXME - def taken; nil end - def skipped; nil end - def sources; [] end - def locked; [] end - end -end diff --git a/lib/arel/algebra/relations/row.rb b/lib/arel/algebra/relations/row.rb deleted file mode 100644 index 84f19e372f..0000000000 --- a/lib/arel/algebra/relations/row.rb +++ /dev/null @@ -1,29 +0,0 @@ -module Arel - class Row - attr_reader :tuple, :relation - - def initialize relation, tuple - @relation = relation - @tuple = tuple - end - - def [](attribute) - attribute.type_cast(tuple[relation.position_of(attribute)]) - end - - def slice(*attributes) - Row.new(relation, attributes.map do |attribute| - # FIXME TESTME method chaining - tuple[relation.relation.position_of(attribute)] - end) - end - - def bind(relation) - Row.new(relation, tuple) - end - - def combine(other, relation) - Row.new(relation, tuple + other.tuple) - end - end -end diff --git a/lib/arel/algebra/relations/utilities/compound.rb b/lib/arel/algebra/relations/utilities/compound.rb deleted file mode 100644 index 0a270f78a1..0000000000 --- a/lib/arel/algebra/relations/utilities/compound.rb +++ /dev/null @@ -1,55 +0,0 @@ -module Arel - class Compound - include Relation - - attr_reader :relation, :engine - - def initialize relation - @relation = relation - @engine = relation.engine - @attributes = nil - @wheres = nil - @groupings = nil - @orders = nil - @havings = nil - @projections = nil - end - - def join?; @relation.join? end - def name; @relation.name end - def table_alias; @relation.table_alias end - def skipped; @relation.skipped end - def taken; @relation.taken end - def joins env; @relation.joins env end - def column_for attr; @relation.column_for attr end - def externalizable?; @relation.externalizable? end - - def sources - @relation.sources - end - - def table - @relation.table - end - - def table_sql(formatter = Sql::TableReference.new(self)) - @relation.table_sql formatter - end - - [:wheres, :groupings, :orders, :havings, :projections].each do |operation_name| - class_eval <<-OPERATION, __FILE__, __LINE__ - def #{operation_name} - @#{operation_name} ||= relation.#{operation_name}.collect { |o| o.bind(self) } - end - OPERATION - end - - def attributes - @attributes ||= relation.attributes.bind(self) - end - - def unoperated_rows - relation.call.collect { |row| row.bind(self) } - end - end -end diff --git a/lib/arel/algebra/relations/utilities/externalization.rb b/lib/arel/algebra/relations/utilities/externalization.rb deleted file mode 100644 index 8e97573f68..0000000000 --- a/lib/arel/algebra/relations/utilities/externalization.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Arel - class Externalization < Compound - include Recursion::BaseCase - - def == other - super || Externalization === other && relation == other.relation - end - - def wheres - [] - end - - def attributes - @attributes ||= Header.new(relation.attributes.map { |a| a.to_attribute(self) }) - end - - def table_sql(formatter = Sql::TableReference.new(relation)) - formatter.select relation.compiler.select_sql, self - end - - # REMOVEME - def name - relation.name + '_external' - end - end -end diff --git a/lib/arel/algebra/relations/utilities/nil.rb b/lib/arel/algebra/relations/utilities/nil.rb deleted file mode 100644 index 04055d0ddb..0000000000 --- a/lib/arel/algebra/relations/utilities/nil.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'singleton' - -module Arel - class Nil - include Relation, Singleton - end -end diff --git a/lib/arel/algebra/relations/writes.rb b/lib/arel/algebra/relations/writes.rb deleted file mode 100644 index 7df6d861a8..0000000000 --- a/lib/arel/algebra/relations/writes.rb +++ /dev/null @@ -1,47 +0,0 @@ -module Arel - class Action < Compound - end - - class Deletion < Action - def call - engine.delete(self) - end - - def to_sql - compiler.delete_sql - end - end - - class Insert < Action - attr_reader :record - - def initialize(relation, record) - super(relation) - @record = record.bind(relation) - end - - def call - engine.create(self) - end - - def eval - unoperated_rows + [Row.new(self, record.values.collect(&:value))] - end - - def to_sql(include_returning = true) - compiler.insert_sql(include_returning) - end - end - - class Update < Insert - alias :assignments :record - - def call - engine.update(self) - end - - def to_sql - compiler.update_sql - end - end -end diff --git a/lib/arel/algebra/value.rb b/lib/arel/algebra/value.rb deleted file mode 100644 index 70e94e0ad0..0000000000 --- a/lib/arel/algebra/value.rb +++ /dev/null @@ -1,53 +0,0 @@ -module Arel - class Value - attr_reader :value, :relation - - def initialize value, relation - @value = value - @relation = relation - end - - def == other - super || - Value === other && - value == other.value && - relation == other.relation - end - - def eval(row) - value - end - - def bind(relation) - Value.new(value, relation) - end - - def to_ordering - self - end - - def inclusion_predicate_sql - value.inclusion_predicate_sql - end - - def exclusion_predicate_sql - value.exclusion_predicate_sql - end - - def equality_predicate_sql - value.equality_predicate_sql - end - - def inequality_predicate_sql - value.inequality_predicate_sql - end - - 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 diff --git a/lib/arel/engines.rb b/lib/arel/engines.rb deleted file mode 100644 index cd848d83e2..0000000000 --- a/lib/arel/engines.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'arel/engines/sql' -require 'arel/engines/memory' diff --git a/lib/arel/engines/memory.rb b/lib/arel/engines/memory.rb deleted file mode 100644 index c0fdf6c5d6..0000000000 --- a/lib/arel/engines/memory.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'arel/engines/memory/relations' -require 'arel/engines/memory/engine' diff --git a/lib/arel/engines/memory/engine.rb b/lib/arel/engines/memory/engine.rb deleted file mode 100644 index 0142c49aa3..0000000000 --- a/lib/arel/engines/memory/engine.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Arel - module Memory - class Engine - def read(relation) - relation.eval - end - alias :create :read - end - end -end diff --git a/lib/arel/engines/memory/relations.rb b/lib/arel/engines/memory/relations.rb deleted file mode 100644 index 046017d78a..0000000000 --- a/lib/arel/engines/memory/relations.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'arel/engines/memory/relations/array' -require 'arel/engines/memory/relations/operations' diff --git a/lib/arel/engines/memory/relations/array.rb b/lib/arel/engines/memory/relations/array.rb deleted file mode 100644 index 028f5c0269..0000000000 --- a/lib/arel/engines/memory/relations/array.rb +++ /dev/null @@ -1,37 +0,0 @@ -module Arel - class Array - include Relation - - attr_reader :array, :attribute_names_and_types - include Recursion::BaseCase - - def initialize(array, attribute_names_and_types) - @array = array - @attribute_names_and_types = attribute_names_and_types - @engine = nil - @attributes = nil - end - - def engine - @engine ||= Memory::Engine.new - end - - def attributes - @attributes ||= begin - attrs = @attribute_names_and_types.collect do |attribute, type| - attribute = type.new(self, attribute) if Symbol === attribute - attribute - end - Header.new(attrs) - end - end - - def format(attribute, value) - value - end - - def eval - @array.collect { |r| Row.new(self, r) } - end - end -end diff --git a/lib/arel/engines/memory/relations/operations.rb b/lib/arel/engines/memory/relations/operations.rb deleted file mode 100644 index 2269fadf72..0000000000 --- a/lib/arel/engines/memory/relations/operations.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Arel - class Alias < Compound - include Recursion::BaseCase - - def eval - unoperated_rows - end - end -end diff --git a/lib/arel/engines/sql.rb b/lib/arel/engines/sql.rb deleted file mode 100644 index 438d028606..0000000000 --- a/lib/arel/engines/sql.rb +++ /dev/null @@ -1,6 +0,0 @@ -require 'arel/engines/sql/attributes' -require 'arel/engines/sql/engine' -require 'arel/engines/sql/relations' -require 'arel/engines/sql/formatters' -require 'arel/engines/sql/core_extensions' -require 'arel/engines/sql/christener' diff --git a/lib/arel/engines/sql/attributes.rb b/lib/arel/engines/sql/attributes.rb deleted file mode 100644 index 50cc802162..0000000000 --- a/lib/arel/engines/sql/attributes.rb +++ /dev/null @@ -1,40 +0,0 @@ -module Arel - module Sql - module Attributes - def self.for(column) - case column.type - when :string then String - when :text then String - when :integer then Integer - when :float then Float - when :decimal then Decimal - when :date then Time - when :datetime then Time - when :timestamp then Time - when :time then Time - when :binary then String - when :boolean then Boolean - else - raise NotImplementedError, "Column type `#{column.type}` is not currently handled" - end - end - - def initialize(column, *args) - @column = column - super(*args) - end - - def type_cast(value) - @column.type_cast(value) - end - - %w(Boolean Decimal Float Integer String Time).each do |klass| - class_eval <<-R - class #{klass} < Arel::Attributes::#{klass} - include Attributes - end - R - end - end - end -end diff --git a/lib/arel/engines/sql/christener.rb b/lib/arel/engines/sql/christener.rb deleted file mode 100644 index b30883e47c..0000000000 --- a/lib/arel/engines/sql/christener.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Arel - module Sql - class Christener - def initialize - @names = {} - end - - def name_for(relation) - table = relation.table - name = table.table_alias || table.name - list = @names[name] ||= [] - - list << table unless list.include? table - - idx = list.index table - name + (idx == 0 ? '' : "_#{idx + 1}") - end - end - end -end diff --git a/lib/arel/engines/sql/compilers/ibm_db_compiler.rb b/lib/arel/engines/sql/compilers/ibm_db_compiler.rb deleted file mode 100644 index 8c5779a35e..0000000000 --- a/lib/arel/engines/sql/compilers/ibm_db_compiler.rb +++ /dev/null @@ -1,48 +0,0 @@ -# +-----------------------------------------------------------------------+ -# | | -# | Copyright (c) 2010 IBM Corporation | -# | | -# | Permission is hereby granted, free of charge, to any person obtaining | -# | a copy of this software and associated documentation files (the | -# | "Software"), to deal in the Software without restriction, including | -# | without limitation the rights to use, copy, modify, merge, publish, | -# | distribute, sublicense, and/or sell copies of the Software, and to | -# | permit persons to whom the Software is furnished to do so, subject to | -# | the following conditions: | -# | | -# | The above copyright notice and this permission notice shall be | -# | included in all copies or substantial portions of the Software. | -# | | -# | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | -# | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | -# | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.| -# | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR | -# | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | -# | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | -# | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | -# | | -# +-----------------------------------------------------------------------+ - -# -# Author: Praveen Devarao <praveendrl@in.ibm.com> -# - -module Arel - module SqlCompiler - class IBM_DBCompiler < GenericCompiler - - def limited_update_conditions(conditions, taken) - quoted_primary_key = engine.quote_table_name(primary_key) - update_conditions = "WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{engine.connection.quote_table_name table.name} #{conditions} " #Note: - ')' not added, limit segment is to be appended - engine.add_limit_offset!(update_conditions,{:limit=>taken,:offset=>nil}) - update_conditions << ")" # Close the sql segment - update_conditions - end - - def add_limit_on_delete(taken) - raise "IBM_DB does not support limit on deletion" # Limiting the number of rows to be deleted is not supported by IBM_DB - end - - end - end -end diff --git a/lib/arel/engines/sql/compilers/mysql_compiler.rb b/lib/arel/engines/sql/compilers/mysql_compiler.rb deleted file mode 100644 index cb12e7377a..0000000000 --- a/lib/arel/engines/sql/compilers/mysql_compiler.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Arel - module SqlCompiler - class MySQLCompiler < GenericCompiler - def limited_update_conditions(conditions, taken) - conditions << " LIMIT #{taken}" - conditions - end - end - end -end - diff --git a/lib/arel/engines/sql/compilers/oracle_compiler.rb b/lib/arel/engines/sql/compilers/oracle_compiler.rb deleted file mode 100644 index 1963454d36..0000000000 --- a/lib/arel/engines/sql/compilers/oracle_compiler.rb +++ /dev/null @@ -1,95 +0,0 @@ -module Arel - module SqlCompiler - class OracleCompiler < GenericCompiler - - def select_sql - where_clauses_array = where_clauses - if limit_or_offset = !taken.blank? || !skipped.blank? - # if need to select first records without ORDER BY and GROUP BY and without DISTINCT - # then can use simple ROWNUM in WHERE clause - if skipped.blank? && groupings.blank? && orders.blank? && select_clauses[0] !~ /^DISTINCT / - where_clauses_array << "ROWNUM <= #{taken}" if !taken.blank? && skipped.blank? && groupings.blank? && orders.blank? - limit_or_offset = false - end - end - - # when limit or offset subquery is used then cannot use FOR UPDATE directly - # and need to construct separate subquery for primary key - if use_subquery_for_lock = limit_or_offset && !locked.blank? - quoted_primary_key = engine.connection.quote_column_name(primary_key) - end - select_attributes_string = use_subquery_for_lock ? quoted_primary_key : select_clauses.join(', ') - - # OracleEnhanced adapter workaround when ORDER BY is used with columns not - # present in DISTINCT columns list - order_clauses_array = if select_attributes_string =~ /DISTINCT.*FIRST_VALUE/ && !orders.blank? - order = order_clauses.join(', ').split(',').map { |s| s.strip }.reject(&:blank?) - order = order.zip((0...order.size).to_a).map { |s,i| "alias_#{i}__ #{'DESC' if s =~ /\bdesc$/i}" } - else - order_clauses - end - - query = build_query \ - "SELECT #{select_attributes_string}", - "FROM #{from_clauses}", - (joins(self) unless joins(self).blank? ), - ("WHERE #{where_clauses_array.join(' AND ')}" unless where_clauses_array.blank? ), - ("GROUP BY #{group_clauses.join(', ')}" unless groupings.blank? ), - ("HAVING #{having_clauses.join(' AND ')}" unless havings.blank? ), - ("ORDER BY #{order_clauses_array.join(', ')}" unless order_clauses_array.blank? ) - - # Use existing method from oracle_enhanced adapter to implement limit and offset using subqueries - engine.connection.add_limit_offset!(query, :limit => taken, :offset => skipped) if limit_or_offset - - if use_subquery_for_lock - build_query \ - "SELECT #{select_clauses.join(', ')}", - "FROM #{from_clauses}", - "WHERE #{quoted_primary_key} IN (#{query})", - "#{locked}" - elsif !locked.blank? - build_query query, "#{locked}" - else - query - end - end - - def delete_sql - where_clauses_array = wheres.collect(&:to_sql) - where_clauses_array << "ROWNUM <= #{taken}" unless taken.blank? - build_query \ - "DELETE", - "FROM #{table_sql}", - ("WHERE #{where_clauses_array.join(' AND ')}" unless where_clauses_array.blank? ) - end - - protected - - def build_update_conditions_sql - conditions = "" - where_clauses_array = wheres.collect(&:to_sql) - # if need to select first records without ORDER BY - # then can use simple ROWNUM in WHERE clause - if !taken.blank? && orders.blank? - where_clauses_array << "ROWNUM <= #{taken}" - end - conditions << " WHERE #{where_clauses_array.join(' AND ')}" unless where_clauses_array.blank? - unless taken.blank? - conditions = limited_update_conditions(conditions, taken) - end - conditions - end - - def limited_update_conditions(conditions, taken) - # need to add ORDER BY only if just taken ones should be updated - conditions << " ORDER BY #{order_clauses.join(', ')}" unless orders.blank? - quoted_primary_key = engine.connection.quote_column_name(primary_key) - subquery = "SELECT #{quoted_primary_key} FROM #{engine.connection.connection.quote_table_name table.name} #{conditions}" - # Use existing method from oracle_enhanced adapter to get taken records when ORDER BY is used - engine.connection.add_limit_offset!(subquery, :limit => taken) unless orders.blank? - "WHERE #{quoted_primary_key} IN (#{subquery})" - end - - end - end -end diff --git a/lib/arel/engines/sql/compilers/postgresql_compiler.rb b/lib/arel/engines/sql/compilers/postgresql_compiler.rb deleted file mode 100644 index 3079451064..0000000000 --- a/lib/arel/engines/sql/compilers/postgresql_compiler.rb +++ /dev/null @@ -1,50 +0,0 @@ -module Arel - module SqlCompiler - class PostgreSQLCompiler < GenericCompiler - - def select_sql - if !relation.orders.blank? && using_distinct_on? - selects = relation.select_clauses - joins = relation.joins(self) - wheres = relation.where_clauses - groups = relation.group_clauses - havings = relation.having_clauses - orders = relation.order_clauses - - subquery_clauses = [ "", - "SELECT #{selects.kind_of?(::Array) ? selects.join("") : selects.to_s}", - "FROM #{relation.from_clauses}", - joins, - ("WHERE #{wheres.join(' AND ')}" unless wheres.empty?), - ("GROUP BY #{groups.join(', ')}" unless groups.empty?), - ("HAVING #{havings.join(' AND ')}" unless havings.empty?) - ].compact.join ' ' - subquery_clauses << " #{locked}" unless locked.blank? - - build_query \ - "SELECT * FROM (#{build_query subquery_clauses}) AS id_list", - "ORDER BY #{aliased_orders(orders)}", - ("LIMIT #{relation.taken}" unless relation.taken.blank? ), - ("OFFSET #{relation.skipped}" unless relation.skipped.blank? ) - else - super - end - end - - def using_distinct_on? - relation.select_clauses.any? { |x| x =~ /DISTINCT ON/ } - end - - def aliased_orders(orders) - # PostgreSQL does not allow arbitrary ordering when using DISTINCT ON, so we work around this - # by wrapping the +sql+ string as a sub-select and ordering in that query. - order = orders.join(', ').split(/,/).map { |s| s.strip }.reject(&:blank?) - order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{'DESC' if s =~ /\bdesc$/i}" }.join(', ') - end - - def supports_insert_with_returning? - engine.connection.send(:postgresql_version) >= 80200 - end - end - end -end diff --git a/lib/arel/engines/sql/compilers/sqlite_compiler.rb b/lib/arel/engines/sql/compilers/sqlite_compiler.rb deleted file mode 100644 index c2f78cd235..0000000000 --- a/lib/arel/engines/sql/compilers/sqlite_compiler.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Arel - module SqlCompiler - class SQLiteCompiler < GenericCompiler - def locked - nil - end - end - end -end diff --git a/lib/arel/engines/sql/core_extensions.rb b/lib/arel/engines/sql/core_extensions.rb deleted file mode 100644 index c8d9ec239e..0000000000 --- a/lib/arel/engines/sql/core_extensions.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'arel/engines/sql/core_extensions/object' -require 'arel/engines/sql/core_extensions/array' -require 'arel/engines/sql/core_extensions/range' -require 'arel/engines/sql/core_extensions/nil_class' diff --git a/lib/arel/engines/sql/core_extensions/array.rb b/lib/arel/engines/sql/core_extensions/array.rb deleted file mode 100644 index 05a1bb774c..0000000000 --- a/lib/arel/engines/sql/core_extensions/array.rb +++ /dev/null @@ -1,24 +0,0 @@ -module Arel - module Sql - module ArrayExtensions - def to_sql(formatter = nil) - if any? - "(" + collect { |e| e.to_sql(formatter) }.join(', ') + ")" - else - "(NULL)" - end - end - - def inclusion_predicate_sql - "IN" - end - - def exclusion_predicate_sql - "NOT IN" - end - - Array.send(:include, self) - end - end -end - diff --git a/lib/arel/engines/sql/core_extensions/nil_class.rb b/lib/arel/engines/sql/core_extensions/nil_class.rb deleted file mode 100644 index 9f060ff36e..0000000000 --- a/lib/arel/engines/sql/core_extensions/nil_class.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Arel - module Sql - module NilClassExtensions - def equality_predicate_sql - 'IS' - end - - def inequality_predicate_sql - 'IS NOT' - end - - NilClass.send(:include, self) - end - end -end diff --git a/lib/arel/engines/sql/core_extensions/object.rb b/lib/arel/engines/sql/core_extensions/object.rb deleted file mode 100644 index d2fda0fe5f..0000000000 --- a/lib/arel/engines/sql/core_extensions/object.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Arel - module Sql - module ObjectExtensions - def to_sql(formatter) - formatter.scalar self - end - - def equality_predicate_sql - '=' - end - - def inequality_predicate_sql - '!=' - end - - Object.send(:include, self) - end - end -end diff --git a/lib/arel/engines/sql/core_extensions/range.rb b/lib/arel/engines/sql/core_extensions/range.rb deleted file mode 100644 index c711ffdde6..0000000000 --- a/lib/arel/engines/sql/core_extensions/range.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Arel - module Sql - module RangeExtensions - def to_sql(formatter = nil) - formatter.range self.begin, self.end - end - - def inclusion_predicate_sql - "BETWEEN" - end - - def exclusion_predicate_sql - "NOT BETWEEN" - end - - Range.send(:include, self) - end - end -end diff --git a/lib/arel/engines/sql/engine.rb b/lib/arel/engines/sql/engine.rb deleted file mode 100644 index ab9dcb48b5..0000000000 --- a/lib/arel/engines/sql/engine.rb +++ /dev/null @@ -1,47 +0,0 @@ -module Arel - module Sql - class Engine - def initialize(ar = nil) - @ar = ar - end - - def connection - @ar && @ar.connection - end - - def adapter_name - @adapter_name ||= case (name = connection.adapter_name) - # map OracleEnanced adapter to Oracle - when /Oracle/ - 'Oracle' - else - name - end - end - - def create(relation) - primary_key_value = if relation.primary_key.blank? - nil - elsif relation.record.is_a?(Hash) - attribute = relation.record.detect { |attr, _| attr.name.to_s == relation.primary_key.to_s } - attribute && attribute.last.value - end - - connection.insert(relation.to_sql(false), nil, relation.primary_key, primary_key_value) - end - - def read(relation) - rows = connection.select_rows(relation.to_sql) - Array.new(rows, relation.attributes) - end - - def update(relation) - connection.update(relation.to_sql) - end - - def delete(relation) - connection.delete(relation.to_sql) - end - end - end -end diff --git a/lib/arel/engines/sql/formatters.rb b/lib/arel/engines/sql/formatters.rb deleted file mode 100644 index da899902ff..0000000000 --- a/lib/arel/engines/sql/formatters.rb +++ /dev/null @@ -1,138 +0,0 @@ -module Arel - module Sql - class Formatter - attr_reader :environment, :christener, :engine - - def initialize(environment) - @environment = environment - @christener = environment.christener - @engine = environment.engine - end - - def name_for thing - @christener.name_for thing - end - - def quote_column_name name - @engine.connection.quote_column_name name - end - - def quote_table_name name - @engine.connection.quote_table_name name - end - - def quote value, column = nil - @engine.connection.quote value, column - end - end - - class SelectClause < Formatter - def attribute(attribute) - "#{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)}" : '') - 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 ordering(ordering) - "#{quote_table_name(name_for(ordering.attribute.original_relation))}.#{quote_column_name(ordering.attribute.name)} #{ordering.direction_sql}" - end - end - - class GroupClause < PassThrough - def attribute(attribute) - "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" - end - end - - class HavingClause < PassThrough - def attribute(attribute) - attribute - 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}) #{quote_table_name(name_for(table))}" - end - - def table(table) - table_name = table.name - return table_name if table_name =~ /\s/ - - unique_name = name_for(table) - - quote_table_name(table_name) + - (table_name != unique_name ? " #{quote_table_name(unique_name)}" : '') - end - end - - class Attribute < WhereCondition - def scalar(scalar) - quote(scalar, environment.column) - end - - def range(left, right) - "#{scalar(left)} AND #{scalar(right)}" - end - end - - class Value < WhereCondition - end - end -end diff --git a/lib/arel/engines/sql/relations.rb b/lib/arel/engines/sql/relations.rb deleted file mode 100644 index d1711d058f..0000000000 --- a/lib/arel/engines/sql/relations.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'arel/engines/sql/relations/utilities/nil' -require 'arel/engines/sql/relations/compiler' -require 'arel/engines/sql/relations/table' diff --git a/lib/arel/engines/sql/relations/compiler.rb b/lib/arel/engines/sql/relations/compiler.rb deleted file mode 100644 index c8511374d9..0000000000 --- a/lib/arel/engines/sql/relations/compiler.rb +++ /dev/null @@ -1,153 +0,0 @@ -module Arel - module SqlCompiler - class GenericCompiler - attr_reader :relation, :engine - - def initialize(relation) - @relation = relation - @engine = relation.engine - end - - def christener - relation.christener - end - - def select_sql - projections = @relation.projections - if Count === projections.first && projections.size == 1 && - (relation.taken.present? || relation.wheres.present?) && relation.joins(self).blank? - subquery = [ - "SELECT 1 FROM #{relation.from_clauses}", build_clauses - ].join ' ' - query = "SELECT COUNT(*) AS count_id FROM (#{subquery}) AS subquery" - else - query = [ - "SELECT #{relation.select_clauses.join(', ')}", - "FROM #{relation.from_clauses}", - build_clauses - ].compact.join ' ' - end - query - end - - def build_clauses - joins = relation.joins(self) - wheres = relation.where_clauses - groups = relation.group_clauses - havings = relation.having_clauses - orders = relation.order_clauses - - clauses = [ "", - joins, - ("WHERE #{wheres.join(' AND ')}" unless wheres.empty?), - ("GROUP BY #{groups.join(', ')}" unless groups.empty?), - ("HAVING #{havings.join(' AND ')}" unless havings.empty?), - ("ORDER BY #{orders.join(', ')}" unless orders.empty?) - ].compact.join ' ' - - offset = relation.skipped - limit = relation.taken - @engine.connection.add_limit_offset!(clauses, :limit => limit, - :offset => offset) if offset || limit - - clauses << " #{locked}" unless locked.blank? - clauses unless clauses.blank? - end - - def delete_sql - build_query \ - "DELETE", - "FROM #{relation.table_sql}", - ("WHERE #{relation.wheres.collect { |x| x.to_sql }.join(' AND ')}" unless relation.wheres.blank? ), - (add_limit_on_delete(relation.taken) unless relation.taken.blank? ) - end - - def add_limit_on_delete(taken) - "LIMIT #{taken}" - end - - def insert_sql(include_returning = true) - insertion_attributes_values_sql = if relation.record.is_a?(Value) - relation.record.value - else - attributes = relation.record.keys.sort_by do |attribute| - attribute.name.to_s - end - - first = attributes.collect do |key| - @engine.connection.quote_column_name(key.name) - end.join(', ') - - second = attributes.collect do |key| - key.format(relation.record[key]) - end.join(', ') - - build_query "(#{first})", "VALUES (#{second})" - end - - build_query \ - "INSERT", - "INTO #{relation.table_sql}", - insertion_attributes_values_sql, - ("RETURNING #{engine.connection.quote_column_name(primary_key)}" if include_returning && relation.compiler.supports_insert_with_returning?) - end - - def supports_insert_with_returning? - false - end - - def update_sql - build_query \ - "UPDATE #{relation.table_sql} SET", - assignment_sql, - build_update_conditions_sql - end - - protected - - def locked - relation.locked - end - - def build_query(*parts) - parts.compact.join(" ") - end - - def assignment_sql - if relation.assignments.respond_to?(:collect) - attributes = relation.assignments.keys.sort_by do |attribute| - attribute.name.to_s - end - - attributes.map do |attribute| - value = relation.assignments[attribute] - "#{@engine.connection.quote_column_name(attribute.name)} = #{attribute.format(value)}" - end.join(", ") - else - relation.assignments.value - end - end - - def build_update_conditions_sql - conditions = "" - conditions << " WHERE #{relation.wheres.map { |x| x.to_sql }.join(' AND ')}" unless relation.wheres.blank? - conditions << " ORDER BY #{relation.order_clauses.join(', ')}" unless relation.orders.blank? - - taken = relation.taken - unless taken.blank? - conditions = limited_update_conditions(conditions, taken) - end - - conditions - end - - def limited_update_conditions(conditions, taken) - conditions << " LIMIT #{taken}" - quoted_primary_key = @engine.connection.quote_column_name(relation.primary_key) - "WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{@engine.connection.quote_table_name relation.table.name} #{conditions})" - end - - end - - end -end diff --git a/lib/arel/engines/sql/relations/table.rb b/lib/arel/engines/sql/relations/table.rb deleted file mode 100644 index b31df7a6d0..0000000000 --- a/lib/arel/engines/sql/relations/table.rb +++ /dev/null @@ -1,100 +0,0 @@ -module Arel - class Table - include Relation, Recursion::BaseCase - - @@engine = nil - @@tables = nil - class << self # FIXME: Do we really need these? - def engine; @@engine; end - def engine= e; @@engine = e; end - - def tables; @@tables; end - def tables= e; @@tables = e; end - end - - attr_reader :name, :engine, :table_alias, :options, :christener - attr_reader :table_exists - alias :table_exists? :table_exists - - def initialize(name, options = {}) - @name = name.to_s - @table_exists = nil - @table_alias = nil - @christener = Sql::Christener.new - @attributes = nil - @matching_attributes = nil - - if options.is_a?(Hash) - @options = options - @engine = options[:engine] || Table.engine - - if options[:as] - as = options[:as].to_s - @table_alias = as unless as == @name - end - else - @engine = options # Table.new('foo', engine) - end - - if @engine.connection - begin - require "arel/engines/sql/compilers/#{@engine.adapter_name.downcase}_compiler" - rescue LoadError - begin - # try to load an externally defined compiler, in case this adapter has defined the compiler on its own. - require "#{@engine.adapter_name.downcase}/arel_compiler" - rescue LoadError - raise "#{@engine.adapter_name} is not supported by Arel." - end - end - - @@tables ||= engine.connection.tables - @table_exists = @@tables.include?(name) || - @engine.connection.table_exists?(name) - end - end - - def as(table_alias) - Table.new(name, options.merge(:as => table_alias)) - end - - def attributes - return @attributes if @attributes - if table_exists? - attrs = columns.collect do |column| - Sql::Attributes.for(column).new(column, self, column.name.to_sym) - end - @attributes = Header.new(attrs) - else - Header.new - end - end - - def column_for(attribute) - has_attribute?(attribute) and columns.detect { |c| c.name == attribute.name.to_s } - end - - def columns - @columns ||= engine.connection.columns(name, "#{name} Columns") - end - - def reset - @columns = nil - @attributes = Header.new([]) - end - - private - def matching_attributes - @matching_attributes ||= Hash[attributes.map { |a| [a.root, true] }] - end - - def has_attribute?(attribute) - matching_attributes.key? attribute.root - 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/nil.rb b/lib/arel/engines/sql/relations/utilities/nil.rb deleted file mode 100644 index 0f7ca5d757..0000000000 --- a/lib/arel/engines/sql/relations/utilities/nil.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Arel - class Nil - def table_sql(formatter = nil); '' end - def name; '' end - end -end diff --git a/lib/arel/recursion/base_case.rb b/lib/arel/recursion/base_case.rb deleted file mode 100644 index 84a526f57c..0000000000 --- a/lib/arel/recursion/base_case.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 diff --git a/lib/arel/session.rb b/lib/arel/session.rb deleted file mode 100644 index f6016431c3..0000000000 --- a/lib/arel/session.rb +++ /dev/null @@ -1,35 +0,0 @@ -module Arel - class Session - @instance = nil - - def self.instance - @instance || new - end - - def self.start - @instance ||= new - yield @instance - ensure - @instance = nil - end - - def create(insert) - insert.call - end - - def read(select) - @read ||= {} - key = select.object_id - return @read[key] if @read.key? key - @read[key] = select.call - end - - def update(update) - update.call - end - - def delete(delete) - delete.call - end - end -end diff --git a/lib/arel/sql_literal.rb b/lib/arel/sql_literal.rb deleted file mode 100644 index a98a9a058c..0000000000 --- a/lib/arel/sql_literal.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Arel - class SqlLiteral < String - def relation - nil - end - - def to_sql(formatter = nil) - self - end - - include Attribute::Expressions - end -end diff --git a/lib/arel/version.rb b/lib/arel/version.rb deleted file mode 100644 index ddf477004d..0000000000 --- a/lib/arel/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module Arel - VERSION = "0.4.0" unless defined?(Arel::VERSION) -end |