Skip to content

Commit

Permalink
initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick Kallen committed Dec 30, 2007
0 parents commit 960bbcb
Show file tree
Hide file tree
Showing 31 changed files with 454 additions and 0 deletions.
Empty file added README
Empty file.
10 changes: 10 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require 'rubygems'
require 'spec'
require 'spec/rake/spectask'

Spec::Rake::SpecTask.new do |t|
t.spec_files = FileList['spec/**/*_spec.rb']
end

desc "Default task is to run specs"
task :default => :spec
24 changes: 24 additions & 0 deletions lib/sql_algebra.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'rubygems'
require 'active_support'

require 'sql_algebra/relations/relation'
require 'sql_algebra/relations/table_relation'
require 'sql_algebra/relations/join_operation'
require 'sql_algebra/relations/join_relation'
require 'sql_algebra/relations/attribute'

require 'sql_algebra/relations/predicates/predicate'
require 'sql_algebra/relations/predicates/binary_predicate'
require 'sql_algebra/relations/predicates/equality_predicate'
require 'sql_algebra/relations/predicates/less_than_predicate'
require 'sql_algebra/relations/predicates/less_than_or_equal_to_predicate'
require 'sql_algebra/relations/predicates/greater_than_predicate'
require 'sql_algebra/relations/predicates/greater_than_or_equal_to_predicate'
require 'sql_algebra/relations/predicates/range_inclusion_predicate'
require 'sql_algebra/relations/predicates/relation_inclusion_predicate'
require 'sql_algebra/relations/predicates/match_predicate'

require 'sql_algebra/extensions/range'

require 'sql_algebra/sql/select'
Empty file.
35 changes: 35 additions & 0 deletions lib/sql_algebra/relations/attribute.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class Attribute
attr_reader :relation, :attribute_name

def initialize(relation, attribute_name)
@relation, @attribute_name = relation, attribute_name
end

def eql?(other)
relation == other.relation and attribute_name == other.attribute_name
end

def ==(other)
EqualityPredicate.new(self, other)
end

def <(other)
LessThanPredicate.new(self, other)
end

def <=(other)
LessThanOrEqualToPredicate.new(self, other)
end

def >(other)
GreaterThanPredicate.new(self, other)
end

def >=(other)
GreaterThanOrEqualToPredicate.new(self, other)
end

def =~(regexp)
MatchPredicate.new(self, regexp)
end
end
16 changes: 16 additions & 0 deletions lib/sql_algebra/relations/join_operation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class JoinOperation
attr_reader :relation1, :relation2

def initialize(relation1, relation2)
@relation1, @relation2 = relation1, relation2
end

def on(*predicates)
JoinRelation.new(relation1, relation2, *predicates)
end

def ==(other)
(relation1 == other.relation1 and relation2 == other.relation2) or
(relation1 == other.relation2 and relation2 == other.relation1)
end
end
13 changes: 13 additions & 0 deletions lib/sql_algebra/relations/join_relation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class JoinRelation < Relation
attr_reader :relation1, :relation2, :predicates

def initialize(relation1, relation2, *predicates)
@relation1, @relation2, @predicates = relation1, relation2, predicates
end

def ==(other)
predicates == other.predicates and
((relation1 == other.relation1 and relation2 == other.relation2) or
(relation2 == other.relation1 and relation1 == other.relation2))
end
end
12 changes: 12 additions & 0 deletions lib/sql_algebra/relations/predicates/binary_predicate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class BinaryPredicate < Predicate
attr_reader :attribute1, :attribute2

def initialize(attribute1, attribute2)
@attribute1, @attribute2 = attribute1, attribute2
end

def ==(other)
super and
(attribute1.eql?(other.attribute1) and attribute2.eql?(other.attribute2))
end
end
7 changes: 7 additions & 0 deletions lib/sql_algebra/relations/predicates/equality_predicate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class EqualityPredicate < BinaryPredicate
def ==(other)
self.class == other.class and
((attribute1.eql?(other.attribute1) and attribute2.eql?(other.attribute2)) or
(attribute1.eql?(other.attribute2) and attribute2.eql?(other.attribute1)))
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class GreaterThanOrEqualToPredicate < BinaryPredicate
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class GreaterThanPredicate < BinaryPredicate
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class LessThanOrEqualToPredicate < BinaryPredicate
end
2 changes: 2 additions & 0 deletions lib/sql_algebra/relations/predicates/less_than_predicate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class LessThanPredicate < BinaryPredicate
end
7 changes: 7 additions & 0 deletions lib/sql_algebra/relations/predicates/match_predicate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class MatchPredicate < Predicate
attr_reader :attribute, :regexp

def initialize(attribute, regexp)
@attribute, @regexp = attribute, regexp
end
end
5 changes: 5 additions & 0 deletions lib/sql_algebra/relations/predicates/predicate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Predicate
def ==(other)
self.class == other.class
end
end
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class RelationInclusionPredicate < Predicate
attr_reader :attribute, :relation

def initialize(attribute, relation)
@attribute, @relation = attribute, relation
end

def ==(other)
super and attribute == other.attribute and relation == other.relation
end
end
13 changes: 13 additions & 0 deletions lib/sql_algebra/relations/relation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Relation
def *(other)
JoinOperation.new(self, other)
end

def [](attribute_name)
Attribute.new(self, attribute_name)
end

def include?(attribute)
RelationInclusionPredicate.new(attribute, self)
end
end
11 changes: 11 additions & 0 deletions lib/sql_algebra/relations/table_relation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class TableRelation < Relation
attr_reader :table

def initialize(table)
@table = table
end

def to_sql
Select.new(:*).from(table)
end
end
23 changes: 23 additions & 0 deletions lib/sql_algebra/sql/select.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Select
attr_reader :attributes, :tables, :predicates

def initialize(*attributes)
@attributes = attributes
end

def from(*tables)
returning self do |select|
@tables = tables
end
end

def where(*predicates)
returning self do |select|
@predicates = predicates
end
end

def ==(other)
attributes == other.attributes and tables == other.tables and predicates == other.predicates
end
end
1 change: 1 addition & 0 deletions spec/extensions/range_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
27 changes: 27 additions & 0 deletions spec/predicates/binary_predicate_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe BinaryPredicate do
before do
@relation1 = TableRelation.new(:foo)
@relation2 = TableRelation.new(:bar)
@attribute1 = Attribute.new(@relation1, :attribute_name)
@attribute2 = Attribute.new(@relation2, :attribute_name)
end

describe BinaryPredicate, '==' do
before do
class ConcreteBinaryPredicate < BinaryPredicate
end
end

it "obtains if attribute1 and attribute2 are identical" do
BinaryPredicate.new(@attribute1, @attribute2).should == BinaryPredicate.new(@attribute1, @attribute2)
BinaryPredicate.new(@attribute1, @attribute2).should_not == BinaryPredicate.new(@attribute1, @attribute1)
end

it "obtains if the concrete type of the BinaryPredicates are identical" do
ConcreteBinaryPredicate.new(@attribute1, @attribute2).should == ConcreteBinaryPredicate.new(@attribute1, @attribute2)
BinaryPredicate.new(@attribute1, @attribute2).should_not == ConcreteBinaryPredicate.new(@attribute1, @attribute2)
end
end
end
25 changes: 25 additions & 0 deletions spec/predicates/equality_predicate_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe EqualityPredicate do
before do
@relation1 = TableRelation.new(:foo)
@relation2 = TableRelation.new(:bar)
@attribute1 = Attribute.new(@relation1, :attribute_name)
@attribute2 = Attribute.new(@relation2, :attribute_name)
end

describe EqualityPredicate, '==' do
it "obtains if attribute1 and attribute2 are identical" do
EqualityPredicate.new(@attribute1, @attribute2).should == EqualityPredicate.new(@attribute1, @attribute2)
EqualityPredicate.new(@attribute1, @attribute2).should_not == EqualityPredicate.new(@attribute1, @attribute1)
end

it "obtains if the concrete type of the predicates are identical" do
EqualityPredicate.new(@attribute1, @attribute2).should_not == BinaryPredicate.new(@attribute1, @attribute2)
end

it "is commutative on the attributes" do
EqualityPredicate.new(@attribute1, @attribute2).should == EqualityPredicate.new(@attribute2, @attribute1)
end
end
end
16 changes: 16 additions & 0 deletions spec/predicates/relation_inclusion_predicate_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe RelationInclusionPredicate do
before do
@relation1 = TableRelation.new(:foo)
@relation2 = TableRelation.new(:bar)
@attribute = @relation1[:baz]
end

describe RelationInclusionPredicate, '==' do
it "obtains if attribute1 and attribute2 are identical" do
RelationInclusionPredicate.new(@attribute, @relation1).should == RelationInclusionPredicate.new(@attribute, @relation1)
RelationInclusionPredicate.new(@attribute, @relation1).should_not == RelationInclusionPredicate.new(@attribute, @relation2)
end
end
end
60 changes: 60 additions & 0 deletions spec/relations/attribute_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe Attribute do
before do
@relation1 = TableRelation.new(:foo)
@relation2 = TableRelation.new(:bar)
end

describe Attribute, '#eql?' do
it "obtains if the relation and attribute name are identical" do
Attribute.new(@relation1, :attribute_name).should be_eql(Attribute.new(@relation1, :attribute_name))
Attribute.new(@relation1, :attribute_name).should_not be_eql(Attribute.new(@relation1, :another_attribute_name))
Attribute.new(@relation1, :attribute_name).should_not be_eql(Attribute.new(@relation2, :attribute_name))
end
end

describe Attribute, 'predications' do
before do
@attribute1 = Attribute.new(@relation1, :attribute_name)
@attribute2 = Attribute.new(@relation2, :attribute_name)
end

describe Attribute, '==' do
it "manufactures an equality predicate" do
(@attribute1 == @attribute2).should == EqualityPredicate.new(@attribute1, @attribute2)
end
end

describe Attribute, '<' do
it "manufactures a less-than predicate" do
(@attribute1 < @attribute2).should == LessThanPredicate.new(@attribute1, @attribute2)
end
end

describe Attribute, '<=' do
it "manufactures a less-than or equal-to predicate" do
(@attribute1 <= @attribute2).should == LessThanOrEqualToPredicate.new(@attribute1, @attribute2)
end
end

describe Attribute, '>' do
it "manufactures a greater-than predicate" do
(@attribute1 > @attribute2).should == GreaterThanPredicate.new(@attribute1, @attribute2)
end
end

describe Attribute, '>=' do
it "manufactures a greater-than or equal to predicate" do
(@attribute1 >= @attribute2).should == GreaterThanOrEqualToPredicate.new(@attribute1, @attribute2)
end
end

describe Attribute, '=~' do
it "manufactures a match predicate" do
(@attribute1 =~ /.*/).should == MatchPredicate.new(@attribute1, @attribute2)
end
end

end
end
29 changes: 29 additions & 0 deletions spec/relations/join_operation_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require File.join(File.dirname(__FILE__), '..', 'spec_helper')

describe JoinOperation, 'between two relations' do
before do
@relation1 = TableRelation.new(:foo)
@relation2 = TableRelation.new(:bar)
end

describe JoinOperation, '==' do
it "obtains if the relations of both joins are identical" do
JoinOperation.new(@relation1, @relation2).should == JoinOperation.new(@relation1, @relation2)
JoinOperation.new(@relation1, @relation2).should_not == JoinOperation.new(@relation1, @relation1)
end

it "is commutative on the relations" do
JoinOperation.new(@relation1, @relation2).should == JoinOperation.new(@relation2, @relation1)
end
end

describe JoinOperation, 'on' do
before do
@predicate = Predicate.new
end

it "manufactures a JoinRelation" do
JoinOperation.new(@relation1, @relation2).on(@predicate).should == JoinRelation.new(@relation1, @relation2, @predicate)
end
end
end
Loading

0 comments on commit 960bbcb

Please sign in to comment.