Returns block's value on #transaction method (#159)

* Returns block's value on #transaction method

* Update src/db/begin_transaction.cr

Co-authored-by: Johannes Müller <straightshoota@gmail.com>

Co-authored-by: Johannes Müller <straightshoota@gmail.com>
This commit is contained in:
Brian J. Cardiff 2022-01-21 10:57:14 -03:00 committed by GitHub
parent 5a7d27e0c5
commit d829b07b01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 2 deletions

View file

@ -175,4 +175,39 @@ describe DB::Transaction do
db.pool.is_available?(cnn).should be_true db.pool.is_available?(cnn).should be_true
end end
end end
it "returns block value when sucess" do
with_dummy_connection do |cnn|
res = cnn.transaction do |tx|
42
end
res.should eq(42)
typeof(res).should eq(Int32 | Nil)
end
end
it "returns value on rollback via method" do
with_dummy_connection do |cnn|
res = cnn.transaction do |tx|
tx.rollback
42
end
res.should eq(42)
typeof(res).should eq(Int32 | Nil)
end
end
it "returns nil on rollback via exception" do
with_dummy_connection do |cnn|
res = cnn.transaction do |tx|
raise DB::Rollback.new
42
end
res.should be_nil
typeof(res).should eq(Int32 | Nil)
end
end
end end

View file

@ -11,12 +11,14 @@ module DB
# The exception thrown is bubbled unless it is a `DB::Rollback`. # The exception thrown is bubbled unless it is a `DB::Rollback`.
# From the yielded object `Transaction#commit` or `Transaction#rollback` # From the yielded object `Transaction#commit` or `Transaction#rollback`
# can be called explicitly. # can be called explicitly.
def transaction # Returns the value of the block.
def transaction(& : Transaction -> T) : T? forall T
tx = begin_transaction tx = begin_transaction
begin begin
yield tx res = yield tx
rescue DB::Rollback rescue DB::Rollback
tx.rollback unless tx.closed? tx.rollback unless tx.closed?
res
rescue e rescue e
unless tx.closed? unless tx.closed?
# Ignore error in rollback. # Ignore error in rollback.
@ -27,6 +29,7 @@ module DB
raise e raise e
else else
tx.commit unless tx.closed? tx.commit unless tx.closed?
res
end end
end end
end end