diff options
-rw-r--r-- | lib/sql_algebra.rb | 4 | ||||
-rw-r--r-- | lib/sql_algebra/relations/join_operation.rb | 2 | ||||
-rw-r--r-- | lib/sql_algebra/relations/relation.rb | 29 | ||||
-rw-r--r-- | spec/relations/join_operation_spec.rb | 10 | ||||
-rw-r--r-- | spec/relations/relation_spec.rb | 51 |
5 files changed, 69 insertions, 27 deletions
diff --git a/lib/sql_algebra.rb b/lib/sql_algebra.rb index 7407dc264b..8adbed150d 100644 --- a/lib/sql_algebra.rb +++ b/lib/sql_algebra.rb @@ -5,7 +5,11 @@ require 'active_support' require 'sql_algebra/relations/relation' require 'sql_algebra/relations/table_relation' require 'sql_algebra/relations/join_operation' +require 'sql_algebra/relations/inner_join_operation' +require 'sql_algebra/relations/left_outer_join_operation' require 'sql_algebra/relations/join_relation' +require 'sql_algebra/relations/inner_join_relation' +require 'sql_algebra/relations/left_outer_join_relation' require 'sql_algebra/relations/attribute' require 'sql_algebra/relations/projection_relation' require 'sql_algebra/relations/selection_relation' diff --git a/lib/sql_algebra/relations/join_operation.rb b/lib/sql_algebra/relations/join_operation.rb index dab8e9e6bd..2b4548a041 100644 --- a/lib/sql_algebra/relations/join_operation.rb +++ b/lib/sql_algebra/relations/join_operation.rb @@ -6,7 +6,7 @@ class JoinOperation end def on(*predicates) - JoinRelation.new(relation1, relation2, *predicates) + relation_class.new(relation1, relation2, *predicates) end def ==(other) diff --git a/lib/sql_algebra/relations/relation.rb b/lib/sql_algebra/relations/relation.rb index f1f8fc5884..bd812b368d 100644 --- a/lib/sql_algebra/relations/relation.rb +++ b/lib/sql_algebra/relations/relation.rb @@ -1,13 +1,34 @@ class Relation - def *(other) - JoinOperation.new(self, other) + def <=>(other) + InnerJoinOperation.new(self, other) end - def [](attribute_name) - Attribute.new(self, attribute_name) + def <<(other) + LeftOuterJoinOperation.new(self, other) + end + + def [](index) + case index + when Symbol + Attribute.new(self, index) + when Range + RangeRelation.new(self, index) + end end def include?(attribute) RelationInclusionPredicate.new(attribute, self) end + + def select(*predicates) + SelectionRelation.new(self, *predicates) + end + + def project(*attributes) + ProjectionRelation.new(self, *attributes) + end + + def order(*attributes) + OrderRelation.new(self, *attributes) + end end
\ No newline at end of file diff --git a/spec/relations/join_operation_spec.rb b/spec/relations/join_operation_spec.rb index 13e50e057e..d75d2d5c93 100644 --- a/spec/relations/join_operation_spec.rb +++ b/spec/relations/join_operation_spec.rb @@ -20,10 +20,16 @@ describe JoinOperation, 'between two relations' do describe JoinOperation, 'on' do before do @predicate = Predicate.new + @join_operation = JoinOperation.new(@relation1, @relation2) + class << @join_operation + def relation_class + JoinRelation + end + end end - it "manufactures a JoinRelation" do - JoinOperation.new(@relation1, @relation2).on(@predicate).should == JoinRelation.new(@relation1, @relation2, @predicate) + it "manufactures a join relation of the appropriate type" do + @join_operation.on(@predicate).should == JoinRelation.new(@relation1, @relation2, @predicate) end end end
\ No newline at end of file diff --git a/spec/relations/relation_spec.rb b/spec/relations/relation_spec.rb index 7434bd563b..6c2c2b8611 100644 --- a/spec/relations/relation_spec.rb +++ b/spec/relations/relation_spec.rb @@ -4,40 +4,45 @@ describe Relation do before do @relation1 = TableRelation.new(:foo) @relation2 = TableRelation.new(:bar) + @attribute1 = Attribute.new(@relation1, :id) + @attribute2 = Attribute.new(@relation1, :name) end - describe Relation, '*' do - it "manufactures a JoinOperation between those two relations" do - (@relation1 * @relation2).should == JoinOperation.new(@relation1, @relation2) + describe Relation, 'joins' do + describe Relation, '<=>' do + it "manufactures an inner join operation between those two relations" do + (@relation1 <=> @relation2).should == InnerJoinOperation.new(@relation1, @relation2) + end + end + + describe Relation, '<<' do + it "manufactures a left outer join operation between those two relations" do + (@relation1 << @relation2).should == LeftOuterJoinOperation.new(@relation1, @relation2) + end end end describe Relation, '[]' do - it "manufactures a attribute" do + it "manufactures an attribute when given a symbol" do @relation1[:id].should be_eql(Attribute.new(@relation1, :id)) end + it "manufactures a range relation when given a range" do + @relation1[1..2].should == RangeRelation.new(@relation1, 1..2) + end + it "raises an error if the named attribute is not part of the relation" do pending end end describe Relation, '#include?' do - before do - @attribute = Attribute.new(@relation1, :id) - end - it "manufactures an inclusion predicate" do - @relation1.include?(@attribute).should == RelationInclusionPredicate.new(@attribute, @relation1) + @relation1.include?(@attribute1).should == RelationInclusionPredicate.new(@attribute1, @relation1) end end describe Relation, '#project' do - before do - @attribute1 = Attribute.new(@relation1, :id) - @attribute2 = Attribute.new(@relation1, :name) - end - it "only allows projecting attributes in the relation" do pending end @@ -46,18 +51,24 @@ describe Relation do pending end - it "manufactures a projected relation" do - @relation1.project(@attribute1, @attribute2).should == ProjectedRelation(@relation1, @attribute1, @attribute2) + it "manufactures a projection relation" do + @relation1.project(@attribute1, @attribute2).should == ProjectionRelation.new(@relation1, @attribute1, @attribute2) end end describe Relation, '#select' do before do - @predicate = EqualityPredicate.new() + @predicate = EqualityPredicate.new(@attribute1, @attribute2) end - it "manufactures a selected relation" do - @relation1.select(@attribute1, @attribute2).should == SelectedRelation(@relation1, @attribute1, @attribute2) + it "manufactures a selection relation" do + @relation1.select(@attribute1, @attribute2).should == SelectionRelation.new(@relation1, @attribute1, @attribute2) end - end + end + + describe Relation, 'order' do + it "manufactures an order relation" do + @relation1.order(@attribute1, @attribute2).should == OrderRelation.new(@relation1, @attribute1, @attribute2) + end + end end
\ No newline at end of file |