diff --git a/Manifest.txt b/Manifest.txt index 947d0ac..06a0582 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -7,4 +7,3 @@ ext/mdbx_ext/database.c ext/mdbx_ext/stats.c lib/mdbx.rb lib/mdbx/database.rb - diff --git a/lib/mdbx.rb b/lib/mdbx.rb index c94a03b..eaa5a7f 100644 --- a/lib/mdbx.rb +++ b/lib/mdbx.rb @@ -10,7 +10,7 @@ require 'mdbx_ext' module MDBX # The version of this gem. - VERSION = '0.1.0' + VERSION = '0.1.1' end # module MDBX diff --git a/lib/mdbx/database.rb b/lib/mdbx/database.rb index f1cacff..19c8e3e 100644 --- a/lib/mdbx/database.rb +++ b/lib/mdbx/database.rb @@ -201,18 +201,24 @@ class MDBX::Database ### pairs. ### def to_a - self.snapshot do - return self.each_pair.to_a - end + in_txn = self.in_transaction? + self.snapshot unless in_txn + + return self.each_pair.to_a + ensure + self.abort unless in_txn end ### Return the entirety of database contents as a Hash. ### def to_h - self.snapshot do - return self.each_pair.to_h - end + in_txn = self.in_transaction? + self.snapshot unless in_txn + + return self.each_pair.to_h + ensure + self.abort unless in_txn end @@ -261,9 +267,12 @@ class MDBX::Database ### Returns a new Array containing all keys in the collection. ### def keys - self.snapshot do - return self.each_key.to_a - end + in_txn = self.in_transaction? + self.snapshot unless in_txn + + return self.each_key.to_a + ensure + self.abort unless in_txn end @@ -271,32 +280,41 @@ class MDBX::Database ### keys. Any given keys that are not found are ignored. ### def slice( *keys ) - self.snapshot do - return keys.each_with_object( {} ) do |key, acc| - val = self[ key ] - acc[ key ] = val if val - end + in_txn = self.in_transaction? + self.snapshot unless in_txn + + return keys.each_with_object( {} ) do |key, acc| + val = self[ key ] + acc[ key ] = val if val end + ensure + self.abort unless in_txn end ### Returns a new Array containing all values in the collection. ### def values - self.snapshot do - return self.each_value.to_a - end + in_txn = self.in_transaction? + self.snapshot unless in_txn + + return self.each_value.to_a + ensure + self.abort unless in_txn end ### Returns a new Array containing values for the given +keys+. ### def values_at( *keys ) - self.snapshot do - return keys.each_with_object( [] ) do |key, acc| - acc << self[ key ] - end + in_txn = self.in_transaction? + self.snapshot unless in_txn + + return keys.each_with_object( [] ) do |key, acc| + acc << self[ key ] end + ensure + self.abort unless in_txn end diff --git a/spec/mdbx/database_spec.rb b/spec/mdbx/database_spec.rb index dc67144..52cafcd 100644 --- a/spec/mdbx/database_spec.rb +++ b/spec/mdbx/database_spec.rb @@ -312,6 +312,19 @@ RSpec.describe( MDBX::Database ) do end expect( db[ 1 ] ).to be_falsey end + + it "doesn't inadvertantly close transactions when using hash-alike methods" do + expect( db.in_transaction? ).to be_falsey + db.transaction + expect( db.in_transaction? ).to be_truthy + db.to_a + db.to_h + db.keys + db.slice( :woop ) + db.values + db.values_at( :woop ) + expect( db.in_transaction? ).to be_truthy + end end