diff options
Diffstat (limited to 'lib/arel/algebra/relations/operations')
-rw-r--r-- | lib/arel/algebra/relations/operations/alias.rb | 7 | ||||
-rw-r--r-- | lib/arel/algebra/relations/operations/group.rb | 12 | ||||
-rw-r--r-- | lib/arel/algebra/relations/operations/join.rb | 64 | ||||
-rw-r--r-- | lib/arel/algebra/relations/operations/order.rb | 18 | ||||
-rw-r--r-- | lib/arel/algebra/relations/operations/project.rb | 20 | ||||
-rw-r--r-- | lib/arel/algebra/relations/operations/skip.rb | 6 | ||||
-rw-r--r-- | lib/arel/algebra/relations/operations/take.rb | 10 | ||||
-rw-r--r-- | lib/arel/algebra/relations/operations/where.rb | 16 |
8 files changed, 153 insertions, 0 deletions
diff --git a/lib/arel/algebra/relations/operations/alias.rb b/lib/arel/algebra/relations/operations/alias.rb new file mode 100644 index 0000000000..0331d98b85 --- /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 diff --git a/lib/arel/algebra/relations/operations/group.rb b/lib/arel/algebra/relations/operations/group.rb new file mode 100644 index 0000000000..2bfc42214b --- /dev/null +++ b/lib/arel/algebra/relations/operations/group.rb @@ -0,0 +1,12 @@ +module Arel + class Group < Compound + attributes :relation, :groupings + deriving :== + + def initialize(relation, *groupings, &block) + @relation = relation + @groupings = (groupings + arguments_from_block(relation, &block)) \ + .collect { |g| g.bind(relation) } + end + end +end diff --git a/lib/arel/algebra/relations/operations/join.rb b/lib/arel/algebra/relations/operations/join.rb new file mode 100644 index 0000000000..e9320f28e1 --- /dev/null +++ b/lib/arel/algebra/relations/operations/join.rb @@ -0,0 +1,64 @@ +module Arel + class Join < Relation + attributes :relation1, :relation2, :predicates + deriving :== + delegate :name, :to => :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) } + 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 + end + + class InnerJoin < Join; end + class OuterJoin < Join; end + class StringJoin < Join + def attributes + relation1.externalize.attributes + end + + def engine + relation1.engine + 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..a589b56997 --- /dev/null +++ b/lib/arel/algebra/relations/operations/order.rb @@ -0,0 +1,18 @@ +module Arel + class Order < Compound + attributes :relation, :orderings + deriving :== + + def initialize(relation, *orderings, &block) + @relation = relation + @orderings = (orderings + arguments_from_block(relation, &block)) \ + .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 + end +end diff --git a/lib/arel/algebra/relations/operations/project.rb b/lib/arel/algebra/relations/operations/project.rb new file mode 100644 index 0000000000..223d320e22 --- /dev/null +++ b/lib/arel/algebra/relations/operations/project.rb @@ -0,0 +1,20 @@ +module Arel + class Project < Compound + attributes :relation, :projections + deriving :== + + def initialize(relation, *projections, &block) + @relation = relation + @projections = (projections + arguments_from_block(relation, &block)) \ + .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..689e06e1c3 --- /dev/null +++ b/lib/arel/algebra/relations/operations/skip.rb @@ -0,0 +1,6 @@ +module Arel + class Skip < Compound + attributes :relation, :skipped + deriving :initialize, :== + end +end diff --git a/lib/arel/algebra/relations/operations/take.rb b/lib/arel/algebra/relations/operations/take.rb new file mode 100644 index 0000000000..eb32ec492e --- /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 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 |