From 1e53dcfa179fdb44385de12fbe201a2575b01074 Mon Sep 17 00:00:00 2001 From: Yurii Rashkovskii Date: Sat, 3 May 2008 09:00:34 +0300 Subject: [PATCH] Initial support for named documents (#44) --- lib/strokedb/document.rb | 3 +- lib/strokedb/document/meta.rb | 16 +++++- spec/lib/strokedb/document/document_spec.rb | 9 ++++ spec/lib/strokedb/document/meta_spec.rb | 56 +++++++++++++++++++++ 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/lib/strokedb/document.rb b/lib/strokedb/document.rb index 210c23e5..58d469bb 100644 --- a/lib/strokedb/document.rb +++ b/lib/strokedb/document.rb @@ -435,7 +435,7 @@ def save!(perform_validation = true) # Updates slots with a specified hash and returns itself. def update_slots(hash) hash.each do |k, v| - self[k] = v + self[k] = v unless self[k] == v end self end @@ -444,6 +444,7 @@ def update_slots(hash) def update_slots!(hash) update_slots(hash).save! end + # Updates nil/false slots with a specified hash and returns itself. # Already set slots are not modified (||= is used). diff --git a/lib/strokedb/document/meta.rb b/lib/strokedb/document/meta.rb index 889595f6..c882074b 100644 --- a/lib/strokedb/document/meta.rb +++ b/lib/strokedb/document/meta.rb @@ -118,6 +118,20 @@ def +(meta) raise "Can't + #{self.class} and #{meta.class}" end end + + def named(*args) + args.unshift StrokeDB.default_store unless args.first.is_a?(StrokeDB::Store) + args << {} unless args.last.is_a?(Hash) + raise InvalidArgumentError, "you should specify name" unless args[1].is_a?(String) + name = args[1] + uuid = ::StrokeDB::Util.sha1_uuid("#{document.uuid}:#{name}") + unless doc = find(args[0],uuid) + doc = create!(args[0],args.last.reverse_merge(:uuid => uuid)) + else + doc.update_slots!(args.last) + end + doc + end CALLBACKS = %w(on_initialization on_load @@ -205,7 +219,7 @@ def find(*args) end # - # Conveniance alias for Meta#find. + # Convenience alias for Meta#find. # alias :all :find diff --git a/spec/lib/strokedb/document/document_spec.rb b/spec/lib/strokedb/document/document_spec.rb index ef22d147..df5a3744 100644 --- a/spec/lib/strokedb/document/document_spec.rb +++ b/spec/lib/strokedb/document/document_spec.rb @@ -90,6 +90,15 @@ @document.bbb.should == true end + it "should batch update slots but should not touch version/previous_version if update haven't changed document" do + @document = @document.update_slots!(:aaa => "aaa", :bbb => true).reload + lambda do + lambda do + @document.update_slots(:aaa => "aaa", :bbb => true) + end.should_not change(@document, :version) + end.should_not change(@document, :previous_version) + end + it "should not save batch update slots" do @document.save! # ensure it is not new doc = @document.reload diff --git a/spec/lib/strokedb/document/meta_spec.rb b/spec/lib/strokedb/document/meta_spec.rb index 20f4aa79..e13f94ab 100644 --- a/spec/lib/strokedb/document/meta_spec.rb +++ b/spec/lib/strokedb/document/meta_spec.rb @@ -363,4 +363,60 @@ def implements_some_name_meta end +end + +describe "Meta#named" do + + before(:each) do + setup_default_store + setup_index + Object.send!(:remove_const,'SomeName') if defined?(SomeName) + SomeName = Meta.new + end + + it "with (name) should create named document with this meta if it does not exist" do + doc = SomeName.named("hello") + doc.should_not be_nil + doc.should be_a_kind_of(Document) + doc.should be_a_kind_of(SomeName) + doc.should_not be_new + doc.versions.all.should have(1).item + end + + it "with (name, slots hash) should create named document with this meta if it does not exist" do + doc = SomeName.named("hello", :some_slot => 1, :another_slot => "2") + doc.should_not be_nil + doc.should be_a_kind_of(Document) + doc.should be_a_kind_of(SomeName) + doc.should_not be_new + doc.versions.all.should have(1).item + doc.some_slot.should == 1 + doc.another_slot.should == "2" + end + + it "with (name) should find named document with this meta if it does exist" do + doc = SomeName.named("hello") + SomeName.named("hello").should == doc + end + + it "with (name, slots hash) should find named document with this meta if it does exist" do + doc = SomeName.named("hello", :some_slot => 1, :another_slot => "2") + SomeName.named("hello", :some_slot => 1, :another_slot => "2").should == doc + end + + it "with (name, slots hash) should find and updated named document with this meta if it does exist but has no such slot pairs" do + doc = SomeName.named("hello", :some_slot => 1) + new_doc = SomeName.named("hello", :some_slot => 1, :another_slot => "2") + new_doc.should_not == doc + new_doc.versions.previous.should == doc + new_doc.another_slot.should == "2" + new_doc = SomeName.named("hello", :some_slot => 2, :another_slot => "2") + new_doc.some_slot.should == 2 + end + + it "should be able to accept store as a first argument" do + doc = SomeName.named("hello") + SomeName.named(StrokeDB.default_store,"hello").should == doc + end + end \ No newline at end of file