diff options
author | Nick Kallen <nkallen@nick-kallens-computer-2.local> | 2008-02-23 19:29:18 -0800 |
---|---|---|
committer | Nick Kallen <nkallen@nick-kallens-computer-2.local> | 2008-02-23 19:29:18 -0800 |
commit | 51fdd769c0cb096d6e6f04afc3ebb91833d625bc (patch) | |
tree | 9e6078f474ccf3424495e567cb39b232ce5c5d25 | |
parent | f10d3be703cada60783c671866dd48194b800002 (diff) | |
download | rails-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.rb | 3 | ||||
-rw-r--r-- | lib/active_relation/relations/deletion.rb | 7 | ||||
-rw-r--r-- | lib/active_relation/relations/insertion.rb | 13 | ||||
-rw-r--r-- | lib/active_relation/relations/relation.rb | 45 | ||||
-rw-r--r-- | lib/active_relation/relations/update.rb | 8 | ||||
-rw-r--r-- | lib/active_relation/sessions/session.rb | 38 | ||||
-rw-r--r-- | lib/active_relation/sql.rb | 2 | ||||
-rw-r--r-- | spec/active_relation/integration/scratch_spec.rb | 18 | ||||
-rw-r--r-- | spec/active_relation/unit/relations/insertion_spec.rb | 9 | ||||
-rw-r--r-- | spec/active_relation/unit/relations/relation_spec.rb | 41 | ||||
-rw-r--r-- | spec/active_relation/unit/relations/update_spec.rb | 1 | ||||
-rw-r--r-- | spec/active_relation/unit/session/session_spec.rb | 70 | ||||
-rw-r--r-- | spec/spec_helper.rb | 4 |
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 |