Skip to content

Instantly share code, notes, and snippets.

@takeru
Created May 7, 2010 10:36
Show Gist options
  • Select an option

  • Save takeru/393272 to your computer and use it in GitHub Desktop.

Select an option

Save takeru/393272 to your computer and use it in GitHub Desktop.
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