Skip to content

Commit

Permalink
Finished event handling for InnerJoin relations
Browse files Browse the repository at this point in the history
  • Loading branch information
Nathan Sobo & Sharon Ly authored and Nathan Sobo committed Feb 26, 2010
1 parent 68a45f3 commit df431df
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 72 deletions.
18 changes: 15 additions & 3 deletions server/lib/monarch/model/changeset.rb
Expand Up @@ -7,7 +7,7 @@ def initialize(record, dirty_fields)
@record, @dirty_fields = record, dirty_fields
@old_state = OldRecordState.new(record)
dirty_fields.each do |field|
old_state[field] = field.remote_value
old_state.preserve_current_remote_value(field)
end
end

Expand All @@ -19,6 +19,18 @@ def wire_representation
wire_representation
end

def inspect
inspect_hash = {}
dirty_fields.each do |field|
inspect_hash[field.name] = {
:old => old_state.field(field.name).value,
:new => field.value
}
end
inspect_hash.inspect
end


protected

class OldRecordState
Expand All @@ -29,8 +41,8 @@ def initialize(record)
@old_field_values_by_column_name = {}
end

def []=(field, old_value)
old_field_values_by_column_name[field.name] = old_value
def preserve_current_remote_value(field)
old_field_values_by_column_name[field.name] = field.remote_value
end

def field(column_or_name)
Expand Down
30 changes: 18 additions & 12 deletions server/lib/monarch/model/relations/inner_join.rb
Expand Up @@ -73,25 +73,31 @@ def subscribe_to_operands
end

inserted_tuples = new_tuples - previous_tuples
updated_tuples = previous_tuples | new_tuples
updated_tuples = previous_tuples & new_tuples
removed_tuples = previous_tuples - new_tuples

inserted_tuples.each {|tuple| on_insert_node.publish(tuple)}
updated_tuples.each {|tuple| on_update_node.publish(tuple, changeset)}
removed_tuples.each {|tuple| on_remove_node.publish(tuple)}
end)

# operand_subscriptions.add(right_operand.on_update do |right_tuple, changeset|
# predicate.find_matching_tuples(changeset.new_state, left_operand).each do |left_tuple|
# composite_tuple = tuple_class.new([left_tuple, right_tuple])
# on_insert_node.publish(composite_tuple)
# end
#
# predicate.find_matching_tuples(changeset.old_state, left_operand).each do |left_tuple|
# composite_tuple = tuple_class.new([left_tuple, right_tuple])
# on_remove_node.publish(composite_tuple)
# end
# end)
operand_subscriptions.add(right_operand.on_update do |right_tuple, changeset|
new_tuples = predicate.find_matching_tuples(changeset.new_state, left_operand).map do |left_tuple|
tuple_class.new([left_tuple, right_tuple])
end

previous_tuples = predicate.find_matching_tuples(changeset.old_state, left_operand).map do |left_tuple|
tuple_class.new([left_tuple, right_tuple])
end

inserted_tuples = new_tuples - previous_tuples
updated_tuples = previous_tuples & new_tuples
removed_tuples = previous_tuples - new_tuples

inserted_tuples.each {|tuple| on_insert_node.publish(tuple)}
updated_tuples.each {|tuple| on_update_node.publish(tuple, changeset)}
removed_tuples.each {|tuple| on_remove_node.publish(tuple)}
end)

operand_subscriptions.add(left_operand.on_remove do |left_tuple|
predicate.find_matching_tuples(left_tuple, right_operand).each do |right_tuple|
Expand Down
137 changes: 80 additions & 57 deletions server/spec/monarch/model/relations/inner_join_spec.rb
Expand Up @@ -180,6 +180,23 @@ module Relations
end
end

describe "when the update causes some composite tuples that are already present to still be present in the join" do
it "fires #on_update events with those composite tuples and the changeset" do
blog = Blog.find("grain")
grain_posts = blog.blog_posts
blog.title = "Did you mean Barbie?"
blog.save

on_insert_calls.should be_empty

on_update_calls.length.should == grain_posts.size
on_update_calls.all? {|call| call[0][Blog] == blog && call[1].wire_representation == {"title" => "Did you mean Barbie?"}}.should be_true
Set.new(on_update_calls.map {|call| call[0][BlogPost]}).should == Set.new(grain_posts.all)

on_remove_calls.should be_empty
end
end

describe "when the update causes some composite tuples to stop being present in the join and others to become present" do
it "fires both #on_remove and #on_insert events" do
post_1 = BlogPost.create(:blog_id => "fun")
Expand All @@ -201,80 +218,86 @@ module Relations
Set.new(on_remove_calls.map {|composite_tuple| composite_tuple[BlogPost]}).should == Set.new(grain_posts.all)
end
end
end

describe "when a record in right operand is updated" do
describe "when the update causes some composite tuples to become present in the join" do
it "fires #on_insert events with all composite tuples that are now present in the join" do
post = BlogPost.create(:blog_id => "fun")
blog = Blog.unsafe_create(:id => "misery")


on_update_calls.should be_empty

post.blog_id = "misery"
post.save

on_insert_calls.length.should == 1

on_insert_calls.first[Blog].should == blog
on_insert_calls.first[BlogPost].should == post

on_update_calls.should be_empty
on_remove_calls.should be_empty
end
end

describe "when the update causes some composite tuples to stop being present in the join" do
it "fires #on_remove events with all composite tuples that were removed from the join" do
blog = Blog.find("grain")
post = blog.blog_posts.first

post.blog_id = "crapola"
post.save

on_insert_calls.should be_empty
on_update_calls.should be_empty
on_remove_calls.length.should == 1

on_remove_calls.first[Blog].should == blog
on_remove_calls.first[BlogPost].should == post
end
end
#
describe "when the update causes some composite tuples that are already present to still be present in the join" do
it "fires #on_update events with those composite tuples and the changeset" do
blog = Blog.find("grain")
grain_posts = blog.blog_posts
blog.title = "Did you mean Barbie?"
blog.save
post = blog.blog_posts.first
post.body = "The sea lions have left the pier. Earthquake imminent?"
post.save

on_insert_calls.should be_empty

on_update_calls.length.should == grain_posts.size
on_update_calls.all? {|call| call[0][Blog] == blog && call[1].wire_representation == {"title" => "Did you mean Barbie?"}}.should be_true
Set.new(on_update_calls.map {|call| call[0][BlogPost]}).should == Set.new(grain_posts.all)
on_update_calls.length.should == 1
on_update_calls.first[0][Blog].should == blog
on_update_calls.first[0][BlogPost].should == post
on_update_calls.first[1].wire_representation.should == { 'body' => "The sea lions have left the pier. Earthquake imminent?" }


on_remove_calls.should be_empty
end
end
end

describe "when a record in right operand is updated" do
describe "when the update causes some composite tuples to become present in the join" do
it "fires #on_insert events with all composite tuples that are now present in the join" do
post_1 = BlogPost.create(:blog_id => "fun")
post_2 = BlogPost.create(:blog_id => "fun")
describe "when the update causes some composite tuples to stop being present in the join and others to become present" do
it "fires both #on_remove and #on_insert events" do
grain_blog = Blog.find("grain")
vegetable_blog = Blog.find("vegetable")
grain_post = grain_blog.blog_posts.first

blog = Blog.unsafe_create(:id => "misery")
blog.id = "fun"
blog.save
grain_post.blog_id = "vegetable"
grain_post.save

on_insert_calls.length.should == 2
on_insert_calls.all? {|composite_tuple| composite_tuple[Blog] == blog }.should be_true
Set.new(on_insert_calls.map {|composite_tuple| composite_tuple[BlogPost]}).should == Set.new([post_1, post_2])
on_insert_calls.length.should == 1
on_insert_calls.first[Blog].should == vegetable_blog
on_insert_calls.first[BlogPost].should == grain_post

on_update_calls.should be_empty
on_remove_calls.should be_empty

on_remove_calls.length.should == 1
on_remove_calls.first[Blog].should == grain_blog
on_remove_calls.first[BlogPost].should == grain_post
end
end

# describe "when the update causes some composite tuples to stop being present in the join" do
# it "fires #on_remove events with all composite tuples that were removed from the join" do
# blog = Blog.find("grain")
# grain_posts = blog.blog_posts
# blog.id = "crapola"
# blog.save
#
# on_insert_calls.should be_empty
# on_update_calls.should be_empty
# on_remove_calls.length.should == grain_posts.size
# on_remove_calls.all? {|composite_tuple| composite_tuple[Blog] == blog }.should be_true
# Set.new(on_remove_calls.map {|composite_tuple| composite_tuple[BlogPost]}).should == Set.new(grain_posts.all)
# end
# end
#
# describe "when the update causes some composite tuples to stop being present in the join and others to become present" do
# it "fires both #on_remove and #on_insert events" do
# post_1 = BlogPost.create(:blog_id => "fun")
# post_2 = BlogPost.create(:blog_id => "fun")
#
# blog = Blog.find("grain")
# grain_posts = blog.blog_posts
# blog.id = "fun"
# blog.save
#
# on_insert_calls.length.should == 2
# on_insert_calls.all? {|composite_tuple| composite_tuple[Blog] == blog }.should be_true
# Set.new(on_insert_calls.map {|composite_tuple| composite_tuple[BlogPost]}).should == Set.new([post_1, post_2])
#
# on_update_calls.should be_empty
#
# on_remove_calls.length.should == grain_posts.size
# on_remove_calls.all? {|composite_tuple| composite_tuple[Blog] == blog }.should be_true
# Set.new(on_remove_calls.map {|composite_tuple| composite_tuple[BlogPost]}).should == Set.new(grain_posts.all)
# end
# end
end

describe "when a record is removed from the left operand" do
Expand All @@ -291,7 +314,7 @@ module Relations
end
end

describe "when a record is removed from the left operand" do
describe "when a record is removed from the right operand" do
it "fires #on_remove events with all composite tuples that were previously in the join" do
blog = Blog.find("grain")
blog_post = blog.blog_posts.first
Expand Down

0 comments on commit df431df

Please sign in to comment.