aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO6
-rw-r--r--lib/active_relation/extensions/array.rb2
-rw-r--r--lib/active_relation/extensions/object.rb2
-rw-r--r--lib/active_relation/primitives.rb2
-rw-r--r--lib/active_relation/primitives/value.rb (renamed from lib/active_relation/primitives/scalar.rb)6
-rw-r--r--lib/active_relation/sql.rb14
-rw-r--r--spec/active_relation/unit/predicates/binary_spec.rb96
-rw-r--r--spec/active_relation/unit/predicates/relation_inclusion_spec.rb20
-rw-r--r--spec/active_relation/unit/relations/join_spec.rb6
-rw-r--r--spec/active_relation/unit/relations/projection_spec.rb2
-rw-r--r--spec/active_relation/unit/relations/relation_spec.rb4
11 files changed, 98 insertions, 62 deletions
diff --git a/TODO b/TODO
index f502b48a3d..fb656ef084 100644
--- a/TODO
+++ b/TODO
@@ -37,13 +37,13 @@ done:
- get some basic aggregations working: users.project(user[:points].max)
- Alias Table Names
- When joining with any sort of aggregation, it needs to be a nested select
-- get a scalar select working: users.project(users[:name], addresses.select(addresses[:user_id] == users[:id]).project(addresses[:id].count))
+- get a value select working: users.project(users[:name], addresses.select(addresses[:user_id] == users[:id]).project(addresses[:id].count))
- Session
-- sublimate scalars to deal with the fact that they must be quoted per engine
+- sublimate values to deal with the fact that they must be quoted per engine
- clean-up singleton monstrosity
- extract hashing module
- hash custom matcher
- make session engine stuff follow laws of demeter - currently doing some odd method chaining? rethink who is responsible for what
- session just calls execute, passing in a connection; by default it gets a connection from the relation.
-- #strategy is now on scalar, attribute and relation; you must admit it's name is confusing given that e.g., relation already has a strategy (Sql::Relation) ... should it be called predicate strategy? operand1.to_sql(operand2.predicate) maybe prefer operand1.cast(operand2) or project or in light of
+- #strategy is now on value, attribute and relation; you must admit it's name is confusing given that e.g., relation already has a strategy (Sql::Relation) ... should it be called predicate strategy? operand1.to_sql(operand2.predicate) maybe prefer operand1.cast(operand2) or project or in light of
- renamed to #format: operand1.format(operand2)
diff --git a/lib/active_relation/extensions/array.rb b/lib/active_relation/extensions/array.rb
index aa4354a78a..4bd20d8121 100644
--- a/lib/active_relation/extensions/array.rb
+++ b/lib/active_relation/extensions/array.rb
@@ -2,7 +2,7 @@ class Array
def to_hash
Hash[*flatten]
end
-
+
def to_sql(strategy = nil)
"(#{collect(&:to_sql).join(', ')})"
end
diff --git a/lib/active_relation/extensions/object.rb b/lib/active_relation/extensions/object.rb
index c1269ee37b..ab874150ed 100644
--- a/lib/active_relation/extensions/object.rb
+++ b/lib/active_relation/extensions/object.rb
@@ -8,7 +8,7 @@ class Object
end
def bind(relation)
- ActiveRelation::Scalar.new(self, relation)
+ ActiveRelation::Value.new(self, relation)
end
def metaclass
diff --git a/lib/active_relation/primitives.rb b/lib/active_relation/primitives.rb
index 7629256034..9909734d24 100644
--- a/lib/active_relation/primitives.rb
+++ b/lib/active_relation/primitives.rb
@@ -1,4 +1,4 @@
require 'active_relation/primitives/attribute'
-require 'active_relation/primitives/scalar'
+require 'active_relation/primitives/value'
require 'active_relation/primitives/expression'
diff --git a/lib/active_relation/primitives/scalar.rb b/lib/active_relation/primitives/value.rb
index d428541a50..ce9497cf34 100644
--- a/lib/active_relation/primitives/scalar.rb
+++ b/lib/active_relation/primitives/value.rb
@@ -1,5 +1,5 @@
module ActiveRelation
- class Scalar
+ class Value
attr_reader :value, :relation
def initialize(value, relation)
@@ -7,11 +7,11 @@ module ActiveRelation
end
def to_sql(strategy = Sql::Predicate.new(relation.engine))
- strategy.scalar value
+ strategy.value value
end
def format(object)
- object.to_sql(Sql::Scalar.new(relation.engine))
+ object.to_sql(Sql::Value.new(relation.engine))
end
def ==(other)
diff --git a/lib/active_relation/sql.rb b/lib/active_relation/sql.rb
index ff00223ce7..fb2177a55b 100644
--- a/lib/active_relation/sql.rb
+++ b/lib/active_relation/sql.rb
@@ -29,8 +29,8 @@ module ActiveRelation
"#{quote_table_name(relation_name)}.#{quote_column_name(attribute_name)}"
end
- def scalar(scalar, column = nil)
- quote(scalar, column)
+ def value(value, column = nil)
+ quote(value, column)
end
def select(select_sql, aliaz)
@@ -39,8 +39,8 @@ module ActiveRelation
end
class Selection < Formatter
- def scalar(scalar)
- scalar
+ def value(value)
+ value
end
end
@@ -61,12 +61,12 @@ module ActiveRelation
@attribute, @engine = attribute, attribute.engine
end
- def scalar(scalar)
- quote(scalar, @attribute.column)
+ def value(value)
+ quote(value, @attribute.column)
end
end
- class Scalar < Predicate
+ class Value < Predicate
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/unit/predicates/binary_spec.rb b/spec/active_relation/unit/predicates/binary_spec.rb
index d552d8b501..13b3f10a8c 100644
--- a/spec/active_relation/unit/predicates/binary_spec.rb
+++ b/spec/active_relation/unit/predicates/binary_spec.rb
@@ -3,17 +3,83 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'spec_helper')
module ActiveRelation
describe Binary do
before do
- @relation1 = Table.new(:users)
- @relation2 = Table.new(:photos)
- @attribute1 = @relation1[:id]
- @attribute2 = @relation2[:id]
+ @relation = Table.new(:users)
+ @attribute1 = @relation[:id]
+ @attribute2 = @relation[:name]
+ @value = "1-asdf".bind(@relation)
class ConcreteBinary < Binary
def predicate_sql
"<=>"
end
end
end
-
+
+ describe '#to_sql' do
+ describe 'when relating two attributes' do
+ it 'manufactures sql with a binary operation' do
+ ConcreteBinary.new(@attribute1, @attribute2).to_sql.should be_like("
+ `users`.`id` <=> `users`.`name`
+ ")
+ end
+ end
+
+ describe 'when relating an attribute and a value' do
+ describe 'when relating to an integer attribute' do
+ it 'formats values as integers' do
+ ConcreteBinary.new(@attribute1, @value).to_sql.should be_like("
+ `users`.`id` <=> 1
+ ")
+ end
+ end
+
+ describe 'when relating to a string attribute' do
+ it 'formats values as strings' do
+ ConcreteBinary.new(@attribute2, @value).to_sql.should be_like("
+ `users`.`name` <=> '1-asdf'
+ ")
+ end
+ end
+ end
+
+ describe 'when relating two values' do
+ before do
+ @another_value = 2.bind(@relation)
+ end
+
+ it 'quotes values appropriate to their type' do
+ ConcreteBinary.new(string = @value, integer = @another_value).to_sql.should be_like("
+ '1-asdf' <=> 2
+ ")
+ end
+ end
+
+ describe 'when relating to an array' do
+ it 'manufactures sql with a list' do
+ pending
+ array = [1, 2, 3]
+ ConcreteBinary.new(@attribute1, array).to_sql.should be_like("
+ `users`.`id` <=> (1,2,3)
+ ")
+ end
+
+ it 'formats values in the array in the type of the attribute' do
+ pending
+ array = ['1-asdf', 2, 3]
+ ConcreteBinary.new(@attribute1, array).to_sql.should be_like("
+ `users`.`id` <=> (1,2,3)
+ ")
+ end
+ end
+
+ describe 'when relating to a relation' do
+ it 'manufactures sql with a subselect' do
+ ConcreteBinary.new(@attribute1, @relation).to_sql.should be_like("
+ `users`.`id` <=> (SELECT `users`.`id`, `users`.`name` FROM `users`)
+ ")
+ end
+ end
+ end
+
describe '==' do
it "obtains if attribute1 and attribute2 are identical" do
Binary.new(@attribute1, @attribute2).should == Binary.new(@attribute1, @attribute2)
@@ -41,23 +107,13 @@ module ActiveRelation
end
describe '#bind' do
- it "distributes over the predicates and attributes" do
- ConcreteBinary.new(@attribute1, @attribute2).bind(@relation2). \
- should == ConcreteBinary.new(@attribute1.bind(@relation2), @attribute2.bind(@relation2))
- end
- end
-
- describe '#to_sql' do
- it 'manufactures sql with a binary operation' do
- ConcreteBinary.new(@attribute1, @attribute2).to_sql.should be_like("
- `users`.`id` <=> `photos`.`id`
- ")
+ before do
+ @another_relation = Table.new(:photos)
end
- it 'appropriately quotes scalars' do
- ConcreteBinary.new(@attribute1, "1-asdf".bind(@relation1)).to_sql.should be_like("
- `users`.`id` <=> 1
- ")
+ it "descends" do
+ ConcreteBinary.new(@attribute1, @attribute2).bind(@another_relation). \
+ should == ConcreteBinary.new(@attribute1.bind(@another_relation), @attribute2.bind(@another_relation))
end
end
end
diff --git a/spec/active_relation/unit/predicates/relation_inclusion_spec.rb b/spec/active_relation/unit/predicates/relation_inclusion_spec.rb
deleted file mode 100644
index af5846b747..0000000000
--- a/spec/active_relation/unit/predicates/relation_inclusion_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-require File.join(File.dirname(__FILE__), '..', '..', '..', 'spec_helper')
-
-module ActiveRelation
- describe RelationInclusion do
- before do
- users = Table.new(:users)
- @relation = users.project(users[:id])
- @attribute = @relation[:id]
- end
-
- describe RelationInclusion, '#to_sql' do
- it "manufactures subselect sql" do
- # 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
- end
-end \ No newline at end of file
diff --git a/spec/active_relation/unit/relations/join_spec.rb b/spec/active_relation/unit/relations/join_spec.rb
index fdc4a4cdf2..fefe069d7b 100644
--- a/spec/active_relation/unit/relations/join_spec.rb
+++ b/spec/active_relation/unit/relations/join_spec.rb
@@ -103,10 +103,10 @@ module ActiveRelation
describe 'with aggregated relations' do
before do
- @aggregation = @relation2 \
+ @aggregation = @relation2 \
.aggregate(@relation2[:user_id], @relation2[:id].count) \
- .group(@relation2[:user_id]) \
- .rename(@relation2[:id].count, :cnt) \
+ .group(@relation2[:user_id]) \
+ .rename(@relation2[:id].count, :cnt) \
.as('photo_count')
end
diff --git a/spec/active_relation/unit/relations/projection_spec.rb b/spec/active_relation/unit/relations/projection_spec.rb
index 9acfead8b8..78766d3308 100644
--- a/spec/active_relation/unit/relations/projection_spec.rb
+++ b/spec/active_relation/unit/relations/projection_spec.rb
@@ -52,7 +52,7 @@ module ActiveRelation
")
end
- it "manufactures sql with scalar selects" do
+ it "manufactures sql with value selects" do
Projection.new(@relation, Projection.new(@relation, @relation[:name])).to_sql.should be_like("
SELECT (SELECT `users`.`name` FROM `users`) FROM `users`
")
diff --git a/spec/active_relation/unit/relations/relation_spec.rb b/spec/active_relation/unit/relations/relation_spec.rb
index 5e434e52a6..b562ec2a2a 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, Scalar.new("arbitrary", @relation))
+ @relation.select("arbitrary").should == Selection.new(@relation, Value.new("arbitrary", @relation))
end
end
@@ -145,7 +145,7 @@ module ActiveRelation
describe '#update' do
it 'manufactures an update relation' do
Session.start do
- assignments = {@relation[:name] => Scalar.new('bob', @relation)}
+ assignments = {@relation[:name] => Value.new('bob', @relation)}
mock(Session.new).update(Update.new(@relation, assignments.bind(@relation)))
@relation.update(assignments).should == @relation
end