mirror of
https://gitea.invidious.io/iv-org/shard-crystal-db.git
synced 2024-08-15 00:53:32 +00:00
233 lines
5.4 KiB
Crystal
233 lines
5.4 KiB
Crystal
require "./spec_helper"
|
|
|
|
private class FooException < Exception
|
|
end
|
|
|
|
describe DB::Transaction do
|
|
it "begin/commit transaction from connection" do
|
|
with_dummy_connection do |cnn|
|
|
tx = cnn.begin_transaction
|
|
tx.commit
|
|
end
|
|
end
|
|
|
|
it "begin/rollback transaction from connection" do
|
|
with_dummy_connection do |cnn|
|
|
tx = cnn.begin_transaction
|
|
tx.rollback
|
|
end
|
|
end
|
|
|
|
it "raise if begin over existing transaction" do
|
|
with_dummy_connection do |cnn|
|
|
cnn.begin_transaction
|
|
expect_raises(DB::Error, "There is an existing transaction in this connection") do
|
|
cnn.begin_transaction
|
|
end
|
|
end
|
|
end
|
|
|
|
it "allow sequential transactions" do
|
|
with_dummy_connection do |cnn|
|
|
tx = cnn.begin_transaction
|
|
tx.rollback
|
|
|
|
tx = cnn.begin_transaction
|
|
tx.commit
|
|
end
|
|
end
|
|
|
|
it "transaction with block from connection should be committed" do
|
|
t = uninitialized DummyDriver::DummyTransaction
|
|
|
|
with_witness do |w|
|
|
with_dummy_connection do |cnn|
|
|
cnn.transaction do |tx|
|
|
if tx.is_a?(DummyDriver::DummyTransaction)
|
|
t = tx
|
|
w.check
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
t.committed.should be_true
|
|
t.rolledback.should be_false
|
|
end
|
|
|
|
it "transaction with block from connection should be rolledback if raise DB::Rollback" do
|
|
t = uninitialized DummyDriver::DummyTransaction
|
|
|
|
with_witness do |w|
|
|
with_dummy_connection do |cnn|
|
|
cnn.transaction do |tx|
|
|
if tx.is_a?(DummyDriver::DummyTransaction)
|
|
t = tx
|
|
w.check
|
|
end
|
|
raise DB::Rollback.new
|
|
end
|
|
end
|
|
end
|
|
|
|
t.rolledback.should be_true
|
|
t.committed.should be_false
|
|
end
|
|
|
|
it "transaction with block from connection should be rolledback if raise" do
|
|
t = uninitialized DummyDriver::DummyTransaction
|
|
|
|
with_witness do |w|
|
|
with_dummy_connection do |cnn|
|
|
expect_raises(FooException) do
|
|
cnn.transaction do |tx|
|
|
if tx.is_a?(DummyDriver::DummyTransaction)
|
|
t = tx
|
|
w.check
|
|
end
|
|
raise FooException.new
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
t.rolledback.should be_true
|
|
t.committed.should be_false
|
|
end
|
|
|
|
it "transaction with block from connection should be committed if `return` is called" do
|
|
t = uninitialized DummyDriver::DummyTransaction
|
|
|
|
with_witness do |w|
|
|
with_dummy_connection do |cnn|
|
|
t = return_from_txn(cnn).as(DummyDriver::DummyTransaction)
|
|
w.check
|
|
end
|
|
end
|
|
|
|
t.rolledback.should be_false
|
|
t.committed.should be_true
|
|
end
|
|
|
|
it "transaction can be committed within block" do
|
|
with_dummy_connection do |cnn|
|
|
cnn.transaction do |tx|
|
|
tx.commit
|
|
end
|
|
end
|
|
end
|
|
|
|
it "transaction can be rolledback within block" do
|
|
with_dummy_connection do |cnn|
|
|
cnn.transaction do |tx|
|
|
tx.rollback
|
|
end
|
|
end
|
|
end
|
|
|
|
it "transaction can be rolledback within block and later raise" do
|
|
with_dummy_connection do |cnn|
|
|
expect_raises(FooException) do
|
|
cnn.transaction do |tx|
|
|
tx.rollback
|
|
raise FooException.new
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
it "transaction can be rolledback within block and later raise DB::Rollback without forwarding it" do
|
|
with_dummy_connection do |cnn|
|
|
cnn.transaction do |tx|
|
|
tx.rollback
|
|
raise DB::Rollback.new
|
|
end
|
|
end
|
|
end
|
|
|
|
it "transaction can't be committed twice" do
|
|
with_dummy_connection do |cnn|
|
|
cnn.transaction do |tx|
|
|
tx.commit
|
|
expect_raises(DB::Error, "Transaction already closed") do
|
|
tx.commit
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
it "transaction can't be rolledback twice" do
|
|
with_dummy_connection do |cnn|
|
|
cnn.transaction do |tx|
|
|
tx.rollback
|
|
expect_raises(DB::Error, "Transaction already closed") do
|
|
tx.rollback
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
it "return connection to pool after transaction block in db" do
|
|
DummyDriver::DummyConnection.clear_connections
|
|
|
|
with_dummy do |db|
|
|
db.transaction do |tx|
|
|
db.pool.is_available?(DummyDriver::DummyConnection.connections.first).should be_false
|
|
end
|
|
db.pool.is_available?(DummyDriver::DummyConnection.connections.first).should be_true
|
|
end
|
|
end
|
|
|
|
it "releasing result_set from within transaction should not return connection to pool" do
|
|
cnn = uninitialized DB::Connection
|
|
with_dummy do |db|
|
|
db.transaction do |tx|
|
|
cnn = tx.connection
|
|
cnn.scalar "1"
|
|
db.pool.is_available?(cnn).should be_false
|
|
end
|
|
db.pool.is_available?(cnn).should be_true
|
|
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
|
|
|
|
private def return_from_txn(cnn)
|
|
cnn.transaction do |tx|
|
|
return tx
|
|
end
|
|
end
|