Created
May 7, 2010 10:36
-
-
Save takeru/393272 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/examples/basic/Gemfile b/examples/basic/Gemfile | |
| index 3e9fbe9..16c32f0 100644 | |
| --- a/examples/basic/Gemfile | |
| +++ b/examples/basic/Gemfile | |
| @@ -5,6 +5,6 @@ bundle_path ".gems/bundler_gems" | |
| # List gems to bundle here: | |
| gem 'appengine-rack', '0.0.7' | |
| -gem 'appengine-apis', '0.0.14' | |
| +gem 'appengine-apis', '0.0.15' | |
| gem 'sinatra' | |
| gem 'rack', '1.0.1' | |
| diff --git a/lib/tiny_ds/base_tx.rb b/lib/tiny_ds/base_tx.rb | |
| index d67a579..6ca17c2 100644 | |
| --- a/lib/tiny_ds/base_tx.rb | |
| +++ b/lib/tiny_ds/base_tx.rb | |
| @@ -167,10 +167,24 @@ module TinyDS | |
| # $app_logger.info "BaseTx.apply dest_journal.nil?=#{dest_journal.nil?}" | |
| if dest_journal.nil? | |
| + # double-check by '_dsj' | |
| + if TinyDS::BaseTx.done_src_journal_key_exist?(dest, src_journal.key) | |
| + raise "why dest_journal is nil? _dsj has key=[#{src_journal.key.inspect}]" | |
| + end | |
| + | |
| # TODO if dest.nil? ... | |
| entities_to_put = dest.send(src_journal.method_name, *(src_journal.args)) | |
| entities_to_put = [entities_to_put] unless entities_to_put.kind_of?(Array) | |
| entities_to_put << DestJournal.new({}, :key=>src_journal.dest_journal_key) | |
| + | |
| + # For double-check by '_dsj' | |
| + _dest = entities_to_put.find{|ent| ent.key==dest.key } | |
| + unless _dest | |
| + _dest = dest | |
| + entities_to_put << _dest | |
| + end | |
| + TinyDS::BaseTx.append_done_src_journal_key(_dest, src_journal.key) | |
| + | |
| TinyDS.batch_save(entities_to_put) | |
| end | |
| } | |
| @@ -203,6 +217,26 @@ module TinyDS | |
| end | |
| nil | |
| end | |
| + | |
| + def done_src_journal_key_exist?(dest, src_journal_key) | |
| + if dest.class.has_property?(:_dsj) # done src journal | |
| + sj_key_str = src_journal_key.inspect | |
| + if dest._dsj.include?(sj_key_str) | |
| + return true | |
| + else | |
| + return false | |
| + end | |
| + end | |
| + return false | |
| + end | |
| + | |
| + def append_done_src_journal_key(dest, src_journal_key) | |
| + if dest.class.has_property?(:_dsj) | |
| + sj_key_str = src_journal_key.inspect | |
| + dest._dsj = ([sj_key_str] + dest._dsj)[0,50] | |
| + end | |
| + return nil | |
| + end | |
| end | |
| end | |
| end | |
| diff --git a/spec/base_tx_spec.rb b/spec/base_tx_spec.rb | |
| index 96c4aef..ee9441b 100644 | |
| --- a/spec/base_tx_spec.rb | |
| +++ b/spec/base_tx_spec.rb | |
| @@ -9,6 +9,17 @@ class User < TinyDS::Base | |
| end | |
| end | |
| +class Account < TinyDS::Base | |
| + property :nickname, :string | |
| + property :money, :integer | |
| + property :_dsj, :list | |
| + def apply_recv_money(amount) | |
| + self.money += amount | |
| + return [self] | |
| + end | |
| +end | |
| + | |
| + | |
| describe "BaseTx" do | |
| before :all do | |
| #AppEngine::Testing.install_test_env | |
| @@ -139,4 +150,82 @@ describe "BaseTx" do | |
| end | |
| describe "should move money AtoB and AtoC" | |
| + | |
| + describe "_dsj : done_src_journal" do | |
| + it "incremented twice if dest_journal is not found" do | |
| + User.has_property?(:_dsj).should == false | |
| + Account.has_property?(:_dsj).should == true | |
| + User.destroy_all | |
| + Account.destroy_all | |
| + TinyDS::BaseTx::SrcJournal.destroy_all | |
| + TinyDS::BaseTx::DestJournal.destroy_all | |
| + | |
| + [User, Account].each do |klass| | |
| + @userA = klass.create(:nickname=>"userA", :money=>10000) | |
| + @userB = klass.create(:nickname=>"userB", :money=>10000) | |
| + @amount = 500 | |
| + @journal = nil | |
| + TinyDS.tx do | |
| + @userA = @userA.reget | |
| + @userA.money -= @amount | |
| + @journal = TinyDS::BaseTx.build_journal( | |
| + @userA, | |
| + {:class=>klass, :key=>@userB.key}, # @userB, | |
| + :apply_recv_money, | |
| + @amount | |
| + ) | |
| + TinyDS.batch_save([@userA, @journal]) | |
| + end | |
| + @userA.reget.money.should == 9500 | |
| + @userB.reget.money.should == 10000 | |
| + TinyDS::BaseTx.apply(@journal) | |
| + @userA.reget.money.should == 9500 | |
| + @userB.reget.money.should == 10500 | |
| + | |
| + TinyDS::BaseTx::DestJournal.destroy_all # delete dest_journal | |
| + if klass==User | |
| + TinyDS::BaseTx.apply(@journal) | |
| + @userA.reget.money.should == 9500 | |
| + @userB.reget.money.should == 11000 | |
| + elsif klass==Account | |
| + proc{ | |
| + TinyDS::BaseTx.apply(@journal) | |
| + }.should raise_error(RuntimeError, /why dest_journal is nil/) | |
| + @userA.reget.money.should == 9500 | |
| + @userB.reget.money.should == 10500 | |
| + else | |
| + raise | |
| + end | |
| + end | |
| + end | |
| + it "_dsj.size is upto 50" do | |
| + @userA = Account.create(:nickname=>"userA", :money=>10000) | |
| + @userB = Account.create(:nickname=>"userB", :money=>10000) | |
| + @amount = 100 | |
| + 100.times do |n| | |
| + @journal = nil | |
| + TinyDS.tx do | |
| + @userA = @userA.reget | |
| + @userA.money -= @amount | |
| + @journal = TinyDS::BaseTx.build_journal( | |
| + @userA, | |
| + {:class=>Account, :key=>@userB.key}, # @userB, | |
| + :apply_recv_money, | |
| + @amount | |
| + ) | |
| + TinyDS.batch_save([@userA, @journal]) | |
| + end | |
| + TinyDS::BaseTx.apply(@journal) | |
| + @userA.reget.money.should == 10000-(n+1)*@amount | |
| + @userB.reget.money.should == 10000+(n+1)*@amount | |
| + @userA.reget._dsj.size.should == 0 | |
| + if n<50 | |
| + @userB.reget._dsj.size.should == n+1 | |
| + else | |
| + @userB.reget._dsj.size.should == 50 | |
| + end | |
| + TinyDS::BaseTx.done_src_journal_key_exist?(@userB.reget, @journal.key).should == true | |
| + end | |
| + end | |
| + end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment