aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Kallen <nkallen@nick-kallens-computer-2.local>2008-03-02 21:10:35 -0800
committerNick Kallen <nkallen@nick-kallens-computer-2.local>2008-03-02 21:10:35 -0800
commit6647a1e08eb9dc3512628882bcf60d421df74228 (patch)
tree204eebc8e9c6e6711331706dbd14815164db2eda
parentc54392872f024d55e8a23ead3065e6119a52b234 (diff)
downloadrails-6647a1e08eb9dc3512628882bcf60d421df74228.tar.gz
rails-6647a1e08eb9dc3512628882bcf60d421df74228.tar.bz2
rails-6647a1e08eb9dc3512628882bcf60d421df74228.zip
scalars are now lifted; the heavy lifting is done by the operations on relation (select, join, etc.)
-rw-r--r--lib/active_relation/extensions/array.rb4
-rw-r--r--lib/active_relation/extensions/class.rb7
-rw-r--r--lib/active_relation/extensions/hash.rb12
-rw-r--r--lib/active_relation/extensions/object.rb16
-rw-r--r--lib/active_relation/predicates.rb2
-rw-r--r--lib/active_relation/primitives.rb1
-rw-r--r--lib/active_relation/primitives/scalar.rb25
-rw-r--r--lib/active_relation/relations/insertion.rb2
-rw-r--r--lib/active_relation/relations/order.rb5
-rw-r--r--lib/active_relation/relations/relation.rb34
-rw-r--r--lib/active_relation/relations/rename.rb4
-rw-r--r--lib/active_relation/relations/update.rb4
-rw-r--r--lib/active_relation/sql.rb2
-rw-r--r--spec/active_relation/unit/predicates/binary_spec.rb2
-rw-r--r--spec/active_relation/unit/predicates/relation_inclusion_spec.rb19
-rw-r--r--spec/active_relation/unit/relations/insertion_spec.rb2
-rw-r--r--spec/active_relation/unit/relations/join_spec.rb2
-rw-r--r--spec/active_relation/unit/relations/relation_spec.rb18
-rw-r--r--spec/active_relation/unit/relations/selection_spec.rb6
-rw-r--r--spec/active_relation/unit/relations/update_spec.rb4
-rw-r--r--spec/active_relation/unit/session/session_spec.rb4
21 files changed, 100 insertions, 75 deletions
diff --git a/lib/active_relation/extensions/array.rb b/lib/active_relation/extensions/array.rb
index 5b6d6d6abd..aa4354a78a 100644
--- a/lib/active_relation/extensions/array.rb
+++ b/lib/active_relation/extensions/array.rb
@@ -2,4 +2,8 @@ class Array
def to_hash
Hash[*flatten]
end
+
+ def to_sql(strategy = nil)
+ "(#{collect(&:to_sql).join(', ')})"
+ end
end \ No newline at end of file
diff --git a/lib/active_relation/extensions/class.rb b/lib/active_relation/extensions/class.rb
deleted file mode 100644
index 72b3bf0c15..0000000000
--- a/lib/active_relation/extensions/class.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class Class
- def memoize(method)
- define_method "#{method}_with_memoization" do |*args|
- end
- alias_method_chain method, :memoization
- end
-end \ No newline at end of file
diff --git a/lib/active_relation/extensions/hash.rb b/lib/active_relation/extensions/hash.rb
index 50864912bf..a33ace5738 100644
--- a/lib/active_relation/extensions/hash.rb
+++ b/lib/active_relation/extensions/hash.rb
@@ -1,11 +1,11 @@
class Hash
- def alias(&block)
- inject({}) do |aliased, (key, value)|
- aliased.merge(yield(key) => value)
- end
+ def bind(relation)
+ descend { |x| x.bind(relation) }
end
- def to_sql(strategy = nil)
- "(#{values.collect(&:to_sql).join(', ')})"
+ def descend(&block)
+ inject({}) do |descendent, (key, value)|
+ descendent.merge(yield(key) => yield(value))
+ end
end
end \ No newline at end of file
diff --git a/lib/active_relation/extensions/object.rb b/lib/active_relation/extensions/object.rb
index b0c7ada999..d13cf9aabb 100644
--- a/lib/active_relation/extensions/object.rb
+++ b/lib/active_relation/extensions/object.rb
@@ -1,18 +1,6 @@
-class Object
- def qualify
- self
- end
-
+class Object
def bind(relation)
- self
- end
-
- def to_sql(strategy = self.strategy)
- strategy.scalar self
- end
-
- def strategy
- ActiveRelation::Sql::Scalar.new(ActiveRelation::Table.engine)
+ ActiveRelation::Scalar.new(self, relation)
end
def metaclass
diff --git a/lib/active_relation/predicates.rb b/lib/active_relation/predicates.rb
index ddc6eab02b..ba926a86e5 100644
--- a/lib/active_relation/predicates.rb
+++ b/lib/active_relation/predicates.rb
@@ -84,7 +84,7 @@ module ActiveRelation
class RelationInclusion < Binary
alias_method :relation, :operand2
-
+
protected
def predicate_sql
'IN'
diff --git a/lib/active_relation/primitives.rb b/lib/active_relation/primitives.rb
index 2ac157297e..7629256034 100644
--- a/lib/active_relation/primitives.rb
+++ b/lib/active_relation/primitives.rb
@@ -1,3 +1,4 @@
require 'active_relation/primitives/attribute'
+require 'active_relation/primitives/scalar'
require 'active_relation/primitives/expression'
diff --git a/lib/active_relation/primitives/scalar.rb b/lib/active_relation/primitives/scalar.rb
new file mode 100644
index 0000000000..fa88404ee3
--- /dev/null
+++ b/lib/active_relation/primitives/scalar.rb
@@ -0,0 +1,25 @@
+module ActiveRelation
+ class Scalar
+ attr_reader :value, :relation
+
+ def initialize(value, relation)
+ @value, @relation = value, relation
+ end
+
+ def to_sql(strategy = self.strategy)
+ strategy.scalar value
+ end
+
+ def strategy
+ ActiveRelation::Sql::Scalar.new(relation.engine)
+ end
+
+ def ==(other)
+ value == other.value
+ end
+
+ def qualify
+ self
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/active_relation/relations/insertion.rb b/lib/active_relation/relations/insertion.rb
index dd5b8ec530..16fe3d5f46 100644
--- a/lib/active_relation/relations/insertion.rb
+++ b/lib/active_relation/relations/insertion.rb
@@ -11,7 +11,7 @@ module ActiveRelation
"INSERT",
"INTO #{table_sql}",
"(#{record.keys.collect(&:to_sql).join(', ')})",
- "VALUES #{record.to_sql}"
+ "VALUES #{record.values.to_sql}"
].join("\n")
end
diff --git a/lib/active_relation/relations/order.rb b/lib/active_relation/relations/order.rb
index e6395aecd7..6949b3acf7 100644
--- a/lib/active_relation/relations/order.rb
+++ b/lib/active_relation/relations/order.rb
@@ -7,8 +7,9 @@ module ActiveRelation
end
def ==(other)
- relation == other.relation and
- orders == other.orders
+ self.class == other.class and
+ relation == other.relation and
+ orders == other.orders
end
def descend(&block)
diff --git a/lib/active_relation/relations/relation.rb b/lib/active_relation/relations/relation.rb
index 3d4ff6613c..1c97cc7035 100644
--- a/lib/active_relation/relations/relation.rb
+++ b/lib/active_relation/relations/relation.rb
@@ -42,11 +42,11 @@ module ActiveRelation
end
def select(*predicates)
- Selection.new(self, *predicates)
+ Selection.new(self, *predicates.collect {|p| p.bind(self)})
end
def project(*attributes)
- Projection.new(self, *attributes)
+ Projection.new(self, *attributes.collect {|a| a.bind(self)})
end
def as(aliaz)
@@ -54,7 +54,7 @@ module ActiveRelation
end
def order(*attributes)
- Order.new(self, *attributes)
+ Order.new(self, *attributes.collect {|a| a.bind(self)})
end
def rename(attribute, aliaz)
@@ -67,11 +67,11 @@ module ActiveRelation
module Writes
def insert(record)
- session.create Insertion.new(self, record); self
+ session.create Insertion.new(self, record.bind(self)); self
end
def update(assignments)
- session.update Update.new(self, assignments); self
+ session.update Update.new(self, assignments.bind(self)); self
end
def delete
@@ -108,14 +108,14 @@ module ActiveRelation
def to_sql(strategy = Sql::Relation.new(engine))
strategy.select [
- "SELECT #{attributes.collect{ |a| a.to_sql(Sql::Projection.new(engine)) }.join(', ')}",
- "FROM #{table_sql}",
- (joins unless joins.blank?),
- ("WHERE #{selects.collect{|s| s.to_sql(Sql::Selection.new(engine))}.join("\n\tAND ")}" unless selects.blank?),
- ("ORDER BY #{orders.collect(&:to_sql)}" unless orders.blank?),
- ("GROUP BY #{groupings.collect(&:to_sql)}" unless groupings.blank?),
- ("LIMIT #{limit.to_sql}" unless limit.blank?),
- ("OFFSET #{offset.to_sql}" unless offset.blank?)
+ "SELECT #{attributes.collect{ |a| a.to_sql(Sql::Projection.new(engine)) }.join(', ')}",
+ "FROM #{table_sql}",
+ (joins unless joins.blank? ),
+ ("WHERE #{selects.collect{|s| s.to_sql(Sql::Selection.new(engine))}.join("\n\tAND ")}" unless selects.blank? ),
+ ("ORDER BY #{orders.collect(&:to_sql)}" unless orders.blank? ),
+ ("GROUP BY #{groupings.collect(&:to_sql)}" unless groupings.blank? ),
+ ("LIMIT #{limit}" unless limit.blank? ),
+ ("OFFSET #{offset}" unless offset.blank? )
].compact.join("\n"), self.alias
end
alias_method :to_s, :to_sql
@@ -127,6 +127,14 @@ module ActiveRelation
def attribute_for_attribute(attribute)
attributes.detect { |a| a =~ attribute }
end
+
+ def bind(relation)
+ self
+ end
+
+ def strategy
+ Sql::Predicate.new(engine)
+ end
def attributes; [] end
def selects; [] end
diff --git a/lib/active_relation/relations/rename.rb b/lib/active_relation/relations/rename.rb
index 9a0e5552c7..ac5484bfff 100644
--- a/lib/active_relation/relations/rename.rb
+++ b/lib/active_relation/relations/rename.rb
@@ -15,7 +15,7 @@ module ActiveRelation
end
def attributes
- relation.attributes.collect(&method(:baptize))
+ relation.attributes.collect(&method(:christen))
end
def descend(&block)
@@ -23,7 +23,7 @@ module ActiveRelation
end
private
- def baptize(attribute)
+ def christen(attribute)
(attribute =~ self.attribute ? attribute.as(pseudonym) : attribute).bind(self) rescue nil
end
end
diff --git a/lib/active_relation/relations/update.rb b/lib/active_relation/relations/update.rb
index 8909ee80a0..c50919af3e 100644
--- a/lib/active_relation/relations/update.rb
+++ b/lib/active_relation/relations/update.rb
@@ -9,7 +9,9 @@ module ActiveRelation
def to_sql(strategy = nil)
[
"UPDATE #{table_sql} SET",
- assignments.inject([]) { |assignments, (attribute, value)| assignments << "#{attribute.to_sql} = #{value.to_sql}" }.join(" "),
+ assignments.inject("") do |assignments, (attribute, value)|
+ assignments << " #{attribute.to_sql} = #{value.to_sql}"
+ end,
("WHERE #{selects.collect(&:to_sql).join('\n\tAND ')}" unless selects.blank?)
].join("\n")
end
diff --git a/lib/active_relation/sql.rb b/lib/active_relation/sql.rb
index a5701ca8cd..99cfc66383 100644
--- a/lib/active_relation/sql.rb
+++ b/lib/active_relation/sql.rb
@@ -20,7 +20,7 @@ module ActiveRelation
end
def select(select_sql, aliaz)
- "(#{select_sql})" + (aliaz ? " AS #{quote_column_name(aliaz)}" : "")
+ "(#{select_sql})" + (aliaz ? " AS #{quote(aliaz)}" : "")
end
end
diff --git a/spec/active_relation/unit/predicates/binary_spec.rb b/spec/active_relation/unit/predicates/binary_spec.rb
index f6466d9105..677d8f3ab4 100644
--- a/spec/active_relation/unit/predicates/binary_spec.rb
+++ b/spec/active_relation/unit/predicates/binary_spec.rb
@@ -55,7 +55,7 @@ module ActiveRelation
end
it 'appropriately quotes scalars' do
- ConcreteBinary.new(@attribute1, "1-asdf").to_sql.should be_like("
+ ConcreteBinary.new(@attribute1, "1-asdf".bind(@relation1)).to_sql.should be_like("
`users`.`id` <=> 1
")
end
diff --git a/spec/active_relation/unit/predicates/relation_inclusion_spec.rb b/spec/active_relation/unit/predicates/relation_inclusion_spec.rb
index 0ac7ccb6e2..af5846b747 100644
--- a/spec/active_relation/unit/predicates/relation_inclusion_spec.rb
+++ b/spec/active_relation/unit/predicates/relation_inclusion_spec.rb
@@ -3,23 +3,16 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'spec_helper')
module ActiveRelation
describe RelationInclusion do
before do
- foo = Table.new(:foo)
- @relation1 = foo.project(foo[:id])
- @relation2 = Table.new(:bar)
- @attribute = @relation1[:id]
- end
-
- describe RelationInclusion, '==' do
- it "obtains if attribute1 and attribute2 are identical" do
- RelationInclusion.new(@attribute, @relation1).should == RelationInclusion.new(@attribute, @relation1)
- RelationInclusion.new(@attribute, @relation1).should_not == RelationInclusion.new(@attribute, @relation2)
- end
+ users = Table.new(:users)
+ @relation = users.project(users[:id])
+ @attribute = @relation[:id]
end
describe RelationInclusion, '#to_sql' do
it "manufactures subselect sql" do
- RelationInclusion.new(@attribute, @relation1).to_sql.should be_like("
- `foo`.`id` IN (SELECT `foo`.`id` FROM `foo`)
+ # remove when sufficient coverage of sql strategies exists
+ RelationInclusion.new(@attribute, @relation).to_sql.should be_like("
+ `users`.`id` IN (SELECT `users`.`id` FROM `users`)
")
end
end
diff --git a/spec/active_relation/unit/relations/insertion_spec.rb b/spec/active_relation/unit/relations/insertion_spec.rb
index b2b239097a..91bf7773c1 100644
--- a/spec/active_relation/unit/relations/insertion_spec.rb
+++ b/spec/active_relation/unit/relations/insertion_spec.rb
@@ -8,7 +8,7 @@ module ActiveRelation
describe '#to_sql' do
it 'manufactures sql inserting the data for one item' do
- Insertion.new(@relation, @relation[:name] => "nick").to_sql.should be_like("
+ Insertion.new(@relation, @relation[:name] => "nick".bind(@relation)).to_sql.should be_like("
INSERT
INTO `users`
(`users`.`name`) VALUES ('nick')
diff --git a/spec/active_relation/unit/relations/join_spec.rb b/spec/active_relation/unit/relations/join_spec.rb
index 64d41effc5..a424239c4b 100644
--- a/spec/active_relation/unit/relations/join_spec.rb
+++ b/spec/active_relation/unit/relations/join_spec.rb
@@ -81,7 +81,7 @@ module ActiveRelation
.aggregate(@relation2[:user_id], @relation2[:id].count) \
.group(@relation2[:user_id]) \
.rename(@relation2[:id].count, :cnt) \
- .as(:photo_count)
+ .as('photo_count')
end
describe '#attributes' do
diff --git a/spec/active_relation/unit/relations/relation_spec.rb b/spec/active_relation/unit/relations/relation_spec.rb
index 3af3b8aa9c..8f35760801 100644
--- a/spec/active_relation/unit/relations/relation_spec.rb
+++ b/spec/active_relation/unit/relations/relation_spec.rb
@@ -89,7 +89,7 @@ module ActiveRelation
end
it "accepts arbitrary strings" do
- @relation.select("arbitrary").should == Selection.new(@relation, "arbitrary")
+ @relation.select("arbitrary").should == Selection.new(@relation, Scalar.new("arbitrary", @relation))
end
end
@@ -100,9 +100,17 @@ module ActiveRelation
end
describe '#aggregate' do
+ before do
+ @expression1 = @attribute1.sum
+ @expression2 = @attribute2.sum
+ end
+
it 'manufactures a group relation' do
@relation.aggregate(@expression1, @expression2).group(@attribute1, @attribute2). \
- should == Aggregation.new(@relation, :expressions => [@expresion, @expression2], :groupings => [@attribute1, @attribute2])
+ should == Aggregation.new(@relation,
+ :expressions => [@expression1, @expression2],
+ :groupings => [@attribute1, @attribute2]
+ )
end
end
@@ -119,7 +127,8 @@ module ActiveRelation
describe '#insert' do
it 'manufactures an insertion relation' do
Session.start do
- mock(Session.new).create(Insertion.new(@relation, record = {@relation[:name] => 'carl'}))
+ record = {@relation[:name] => 'carl'}
+ mock(Session.new).create(Insertion.new(@relation, record.bind(@relation)))
@relation.insert(record).should == @relation
end
end
@@ -128,7 +137,8 @@ module ActiveRelation
describe '#update' do
it 'manufactures an update relation' do
Session.start do
- mock(Session.new).update(Update.new(@relation, assignments = {@relation[:name] => 'bob'}))
+ assignments = {@relation[:name] => Scalar.new('bob', @relation)}
+ mock(Session.new).update(Update.new(@relation, assignments.bind(@relation)))
@relation.update(assignments).should == @relation
end
end
diff --git a/spec/active_relation/unit/relations/selection_spec.rb b/spec/active_relation/unit/relations/selection_spec.rb
index 3a18d4ae6e..d5e0c6a9f6 100644
--- a/spec/active_relation/unit/relations/selection_spec.rb
+++ b/spec/active_relation/unit/relations/selection_spec.rb
@@ -4,12 +4,12 @@ module ActiveRelation
describe Selection do
before do
@relation = Table.new(:users)
- @predicate = Equality.new(@relation[:id], 1)
+ @predicate = Equality.new(@relation[:id], 1.bind(@relation))
end
describe '#initialize' do
it "manufactures nested selection relations if multiple predicates are provided" do
- @predicate2 = LessThan.new(@relation[:age], 2)
+ @predicate2 = LessThan.new(@relation[:age], 2.bind(@relation))
Selection.new(@relation, @predicate, @predicate2). \
should == Selection.new(Selection.new(@relation, @predicate2), @predicate)
end
@@ -39,7 +39,7 @@ module ActiveRelation
end
it "allows arbitrary sql" do
- Selection.new(@relation, "asdf").to_sql.should be_like("
+ Selection.new(@relation, "asdf".bind(@relation)).to_sql.should be_like("
SELECT `users`.`id`, `users`.`name`
FROM `users`
WHERE asdf
diff --git a/spec/active_relation/unit/relations/update_spec.rb b/spec/active_relation/unit/relations/update_spec.rb
index 2cd3eb9d11..cad14fd5ec 100644
--- a/spec/active_relation/unit/relations/update_spec.rb
+++ b/spec/active_relation/unit/relations/update_spec.rb
@@ -8,14 +8,14 @@ module ActiveRelation
describe '#to_sql' do
it 'manufactures sql updating attributes' do
- Update.new(@relation, @relation[:name] => "nick").to_sql.should be_like("
+ Update.new(@relation, @relation[:name] => "nick".bind(@relation)).to_sql.should be_like("
UPDATE `users`
SET `users`.`name` = 'nick'
")
end
it 'manufactures sql updating a selection relation' do
- Update.new(@relation.select(@relation[:id].equals(1)), @relation[:name] => "nick").to_sql.should be_like("
+ Update.new(@relation.select(@relation[:id].equals(1)), @relation[:name] => "nick".bind(@relation)).to_sql.should be_like("
UPDATE `users`
SET `users`.`name` = 'nick'
WHERE `users`.`id` = 1
diff --git a/spec/active_relation/unit/session/session_spec.rb b/spec/active_relation/unit/session/session_spec.rb
index 1ac69976b5..89d96ef323 100644
--- a/spec/active_relation/unit/session/session_spec.rb
+++ b/spec/active_relation/unit/session/session_spec.rb
@@ -32,8 +32,8 @@ module ActiveRelation
describe Session::CRUD do
before do
- @insert = Insertion.new(@relation, @relation[:name] => 'nick')
- @update = Update.new(@relation, @relation[:name] => 'nick')
+ @insert = Insertion.new(@relation, @relation[:name] => 'nick'.bind(@relation))
+ @update = Update.new(@relation, @relation[:name] => 'nick'.bind(@relation))
@delete = Deletion.new(@relation)
@select = @relation
end