aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Kallen <nkallen@nick-kallens-computer-2.local>2008-02-23 19:29:18 -0800
committerNick Kallen <nkallen@nick-kallens-computer-2.local>2008-02-23 19:29:18 -0800
commit51fdd769c0cb096d6e6f04afc3ebb91833d625bc (patch)
tree9e6078f474ccf3424495e567cb39b232ce5c5d25
parentf10d3be703cada60783c671866dd48194b800002 (diff)
downloadrails-51fdd769c0cb096d6e6f04afc3ebb91833d625bc.tar.gz
rails-51fdd769c0cb096d6e6f04afc3ebb91833d625bc.tar.bz2
rails-51fdd769c0cb096d6e6f04afc3ebb91833d625bc.zip
Introduced concept of session. It does not yet support multiple databases, nor transactions, but it's a start!
-rw-r--r--lib/active_relation/relations.rb3
-rw-r--r--lib/active_relation/relations/deletion.rb7
-rw-r--r--lib/active_relation/relations/insertion.rb13
-rw-r--r--lib/active_relation/relations/relation.rb45
-rw-r--r--lib/active_relation/relations/update.rb8
-rw-r--r--lib/active_relation/sessions/session.rb38
-rw-r--r--lib/active_relation/sql.rb2
-rw-r--r--spec/active_relation/integration/scratch_spec.rb18
-rw-r--r--spec/active_relation/unit/relations/insertion_spec.rb9
-rw-r--r--spec/active_relation/unit/relations/relation_spec.rb41
-rw-r--r--spec/active_relation/unit/relations/update_spec.rb1
-rw-r--r--spec/active_relation/unit/session/session_spec.rb70
-rw-r--r--spec/spec_helper.rb4
13 files changed, 189 insertions, 70 deletions
diff --git a/lib/active_relation/relations.rb b/lib/active_relation/relations.rb
index 97c17b3792..f992fca8be 100644
--- a/lib/active_relation/relations.rb
+++ b/lib/active_relation/relations.rb
@@ -11,4 +11,5 @@ require 'active_relation/relations/rename'
require 'active_relation/relations/deletion'
require 'active_relation/relations/insertion'
require 'active_relation/relations/update'
-require 'active_relation/relations/alias' \ No newline at end of file
+require 'active_relation/relations/alias'
+require 'active_relation/sessions/session' \ No newline at end of file
diff --git a/lib/active_relation/relations/deletion.rb b/lib/active_relation/relations/deletion.rb
index 4ac40a146b..f3d81baf27 100644
--- a/lib/active_relation/relations/deletion.rb
+++ b/lib/active_relation/relations/deletion.rb
@@ -10,6 +10,11 @@ module ActiveRelation
"FROM #{table_sql}",
("WHERE #{selects.collect(&:to_sql).join('\n\tAND ')}" unless selects.blank?)
].compact.join("\n")
- end
+ end
+
+ def ==(other)
+ self.class == other.class and
+ relation == other.relation
+ 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 31e4339ee0..dd5b8ec530 100644
--- a/lib/active_relation/relations/insertion.rb
+++ b/lib/active_relation/relations/insertion.rb
@@ -11,13 +11,14 @@ module ActiveRelation
"INSERT",
"INTO #{table_sql}",
"(#{record.keys.collect(&:to_sql).join(', ')})",
- "VALUES #{inserts.collect(&:to_sql).join(', ')}"
+ "VALUES #{record.to_sql}"
].join("\n")
- end
-
- protected
- def inserts
- relation.inserts + [record]
+ end
+
+ def ==(other)
+ self.class == other.class and
+ relation == other.relation and
+ record == other.record
end
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/relation.rb b/lib/active_relation/relations/relation.rb
index f20561c5b2..1d5e194923 100644
--- a/lib/active_relation/relations/relation.rb
+++ b/lib/active_relation/relations/relation.rb
@@ -2,18 +2,22 @@ module ActiveRelation
class Relation
include Sql::Quoting
- module Iteration
- include Enumerable
-
+ def session
+ Session.instance
+ end
+
+ module Enumerable
+ include ::Enumerable
+
def each(&block)
- connection.select_all(to_s).each(&block)
+ session.read(self).each(&block)
end
-
+
def first
- connection.select_one(to_s)
+ session.read(self).first
end
end
- include Iteration
+ include Enumerable
module Operations
def join(other)
@@ -58,18 +62,25 @@ module ActiveRelation
def rename(attribute, aliaz)
Rename.new(self, attribute => aliaz)
end
-
- def insert(record)
- Insertion.new(self, record)
- end
-
- def delete
- Deletion.new(self)
- end
-
+
def aggregate(*expressions)
AggregateOperation.new(self, expressions)
end
+
+ module Writes
+ def insert(record)
+ session.create Insertion.new(self, record); self
+ end
+
+ def update(assignments)
+ session.update Update.new(self, assignments); self
+ end
+
+ def delete
+ session.delete Deletion.new(self); self
+ end
+ end
+ include Writes
JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do
def on(*predicates)
@@ -84,7 +95,7 @@ module ActiveRelation
end
end
include Operations
-
+
def aggregation?
false
end
diff --git a/lib/active_relation/relations/update.rb b/lib/active_relation/relations/update.rb
index d28608fdd5..8909ee80a0 100644
--- a/lib/active_relation/relations/update.rb
+++ b/lib/active_relation/relations/update.rb
@@ -12,6 +12,12 @@ module ActiveRelation
assignments.inject([]) { |assignments, (attribute, value)| assignments << "#{attribute.to_sql} = #{value.to_sql}" }.join(" "),
("WHERE #{selects.collect(&:to_sql).join('\n\tAND ')}" unless selects.blank?)
].join("\n")
- end
+ end
+
+ def ==(other)
+ self.class == other.class and
+ relation == other.relation and
+ assignments == other.assignments
+ end
end
end \ No newline at end of file
diff --git a/lib/active_relation/sessions/session.rb b/lib/active_relation/sessions/session.rb
new file mode 100644
index 0000000000..d6e2ae7169
--- /dev/null
+++ b/lib/active_relation/sessions/session.rb
@@ -0,0 +1,38 @@
+require 'singleton'
+
+module ActiveRelation
+ class Session
+ include Singleton
+
+ module CRUD
+ def connection
+ ActiveRecord::Base.connection
+ end
+
+ def create(insert)
+ connection.insert(insert.to_sql)
+ end
+
+ def read(select)
+ connection.select_all(select.to_sql)
+ end
+
+ def update(update)
+ connection.update(update.to_sql)
+ end
+
+ def delete(delete)
+ connection.delete(delete.to_sql)
+ end
+ end
+ include CRUD
+
+ module Transactions
+ end
+ include Transactions
+
+ module UnitOfWork
+ end
+ include UnitOfWork
+ end
+end \ No newline at end of file
diff --git a/lib/active_relation/sql.rb b/lib/active_relation/sql.rb
index 0384de44ef..85bcb4107b 100644
--- a/lib/active_relation/sql.rb
+++ b/lib/active_relation/sql.rb
@@ -2,7 +2,7 @@ module ActiveRelation
module Sql
module Quoting
def connection
- ActiveRecord::Base.connection
+ Session.instance.connection
end
delegate :quote_table_name, :quote_column_name, :quote, :to => :connection
diff --git a/spec/active_relation/integration/scratch_spec.rb b/spec/active_relation/integration/scratch_spec.rb
index 4b02b22a11..d6ec030518 100644
--- a/spec/active_relation/integration/scratch_spec.rb
+++ b/spec/active_relation/integration/scratch_spec.rb
@@ -136,24 +136,6 @@ describe 'ActiveRelation', 'A proposed refactoring to ActiveRecord, introducing
""")
end
- describe 'write operations' do
- it 'generates the query for user.destroy' do
- @user.delete.to_sql.should be_like("""
- DELETE
- FROM `users`
- WHERE `users`.`id` = 1
- """)
- end
-
- it 'generates an efficient query for two User.creates -- UnitOfWork is within reach!' do
- @users.insert(@users[:name] => "humpty").insert(@users[:name] => "dumpty").to_sql.should be_like("""
- INSERT
- INTO `users`
- (`users`.`name`) VALUES ('humpty'), ('dumpty')
- """)
- end
- end
-
describe 'with_scope' do
it 'obviates the need for with_scope merging logic since, e.g.,
`with_scope :conditions => ...` is just a #select operation on the relation' do
diff --git a/spec/active_relation/unit/relations/insertion_spec.rb b/spec/active_relation/unit/relations/insertion_spec.rb
index a0427bc74f..a39c4aeaf3 100644
--- a/spec/active_relation/unit/relations/insertion_spec.rb
+++ b/spec/active_relation/unit/relations/insertion_spec.rb
@@ -14,15 +14,6 @@ module ActiveRelation
(`users`.`name`) VALUES ('nick')
""")
end
-
- it 'manufactures sql inserting the data for multiple items' do
- nested_insertion = Insertion.new(@relation, @relation[:name] => "cobra")
- Insertion.new(nested_insertion, nested_insertion[:name] => "commander").to_sql.should be_like("""
- INSERT
- INTO `users`
- (`users`.`name`) VALUES ('cobra'), ('commander')
- """)
- end
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/unit/relations/relation_spec.rb b/spec/active_relation/unit/relations/relation_spec.rb
index a80df928c7..d3252c658b 100644
--- a/spec/active_relation/unit/relations/relation_spec.rb
+++ b/spec/active_relation/unit/relations/relation_spec.rb
@@ -36,13 +36,13 @@ module ActiveRelation
end
end
- describe '#Expression?' do
+ describe '#aggregation?' do
it "returns false" do
@relation.should_not be_aggregation
end
end
- describe 'read operations' do
+ describe Relation::Operations do
describe 'joins' do
before do
@predicate = @relation[:id].equals(@relation[:id])
@@ -105,20 +105,35 @@ module ActiveRelation
should == Aggregation.new(@relation, :expressions => [@expresion, @expression2], :groupings => [@attribute1, @attribute2])
end
end
- end
-
- describe 'write operations' do
- describe '#delete' do
- it 'manufactures a deletion relation' do
- @relation.delete.should be_kind_of(Deletion)
+
+ describe Relation::Operations::Writes do
+ describe '#delete' do
+ it 'manufactures a deletion relation' do
+ mock(Session.instance).delete(Deletion.new(@relation))
+ @relation.delete.should == @relation
+ end
end
- end
-
- describe '#insert' do
- it 'manufactures an insertion relation' do
- @relation.insert(record = {:id => 1}).should be_kind_of(Insertion)
+
+ describe '#insert' do
+ it 'manufactures an insertion relation' do
+ mock(Session.instance).create(Insertion.new(@relation, record = {@relation[:name] => 'carl'}))
+ @relation.insert(record).should == @relation
+ end
+ end
+
+ describe '#update' do
+ it 'manufactures an update relation' do
+ mock(Session.instance).update(Update.new(@relation, assignments = {@relation[:name] => 'bob'}))
+ @relation.update(assignments).should == @relation
+ end
end
end
end
+
+ describe Relation::Enumerable do
+ it "is enumerable" do
+ pending
+ end
+ end
end
end \ No newline at end of file
diff --git a/spec/active_relation/unit/relations/update_spec.rb b/spec/active_relation/unit/relations/update_spec.rb
index c26e7fb525..642d652057 100644
--- a/spec/active_relation/unit/relations/update_spec.rb
+++ b/spec/active_relation/unit/relations/update_spec.rb
@@ -21,7 +21,6 @@ module ActiveRelation
WHERE `users`.`id` = 1
""")
end
-
end
end
end \ No newline at end of file
diff --git a/spec/active_relation/unit/session/session_spec.rb b/spec/active_relation/unit/session/session_spec.rb
new file mode 100644
index 0000000000..ddd748334a
--- /dev/null
+++ b/spec/active_relation/unit/session/session_spec.rb
@@ -0,0 +1,70 @@
+require File.join(File.dirname(__FILE__), '..', '..', '..', 'spec_helper')
+
+module ActiveRelation
+ describe Session do
+ before do
+ @relation = Table.new(:users)
+ @session = Session.instance
+ end
+
+ describe Singleton do
+ it "is a singleton" do
+ Session.instance.should be_equal(Session.instance)
+ lambda { Session.new }.should raise_error
+ end
+ end
+
+ describe Session::CRUD do
+ before do
+ @insert = Insertion.new(@relation, @relation[:name] => 'nick')
+ @update = Update.new(@relation, @relation[:name] => 'nick')
+ @delete = Deletion.new(@relation)
+ @select = @relation
+ end
+
+ describe '#create' do
+ it "should execute an insertion on the connection" do
+ mock(@session.connection).insert(@insert.to_sql)
+ @session.create(@insert)
+ end
+ end
+
+ describe '#read' do
+ it "should execute an selection on the connection" do
+ mock(@session.connection).select_all(@select.to_sql)
+ @session.read(@select)
+ end
+ end
+
+ describe '#update' do
+ it "should execute an update on the connection" do
+ mock(@session.connection).update(@update.to_sql)
+ @session.update(@update)
+ end
+ end
+
+ describe '#delete' do
+ it "should execute a delete on the connection" do
+ mock(@session.connection).delete(@delete.to_sql)
+ @session.delete(@delete)
+ end
+ end
+ end
+
+ describe Session::Transactions do
+ describe '#begin' do
+ end
+
+ describe '#end' do
+ end
+ end
+
+ describe Session::UnitOfWork do
+ describe '#flush' do
+ end
+
+ describe '#clear' do
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index e3508aac90..59202dc9f0 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -7,7 +7,7 @@ Dir["#{dir}/matchers/*"].each { |m| require "#{dir}/matchers/#{File.basename(m)}
require 'active_relation'
ActiveRecord::Base.configurations = {
- 'sql_algebra_test' => {
+ 'test' => {
:adapter => 'mysql',
:username => 'root',
:password => 'password',
@@ -15,7 +15,7 @@ ActiveRecord::Base.configurations = {
:database => 'sql_algebra_test',
},
}
-ActiveRecord::Base.establish_connection 'sql_algebra_test'
+ActiveRecord::Base.establish_connection 'test'
class Hash
def shift