diff --git a/ext/mdbx_ext/stats.c b/ext/mdbx_ext/stats.c index 6ba3b09..7ac003d 100644 --- a/ext/mdbx_ext/stats.c +++ b/ext/mdbx_ext/stats.c @@ -148,7 +148,7 @@ rmdbx_gather_reader_stats( { VALUE readers = rb_ary_new(); - mdbx_reader_list( db->env, reader_list_callback, (void*)readers ); + mdbx_reader_list( db->env, reader_list_callback, (void*)readers ); rb_hash_aset( stat, ID2SYM(rb_intern("readers")), readers ); return; diff --git a/lib/mdbx/database.rb b/lib/mdbx/database.rb index 19c8e3e..8548569 100644 --- a/lib/mdbx/database.rb +++ b/lib/mdbx/database.rb @@ -201,24 +201,18 @@ class MDBX::Database ### pairs. ### def to_a - in_txn = self.in_transaction? - self.snapshot unless in_txn - - return self.each_pair.to_a - ensure - self.abort unless in_txn + return self.conditional_snapshot do + self.each_pair.to_a + end end ### Return the entirety of database contents as a Hash. ### def to_h - in_txn = self.in_transaction? - self.snapshot unless in_txn - - return self.each_pair.to_h - ensure - self.abort unless in_txn + return self.conditional_snapshot do + self.each_pair.to_h + end end @@ -267,12 +261,9 @@ class MDBX::Database ### Returns a new Array containing all keys in the collection. ### def keys - in_txn = self.in_transaction? - self.snapshot unless in_txn - - return self.each_key.to_a - ensure - self.abort unless in_txn + return self.conditional_snapshot do + self.each_key.to_a + end end @@ -280,41 +271,32 @@ class MDBX::Database ### keys. Any given keys that are not found are ignored. ### def slice( *keys ) - 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 + return self.conditional_snapshot do + keys.each_with_object( {} ) do |key, acc| + val = self[ key ] + acc[ key ] = val if val + end end - ensure - self.abort unless in_txn end ### Returns a new Array containing all values in the collection. ### def values - in_txn = self.in_transaction? - self.snapshot unless in_txn - - return self.each_value.to_a - ensure - self.abort unless in_txn + return self.conditional_snapshot do + self.each_value.to_a + end end ### Returns a new Array containing values for the given +keys+. ### def values_at( *keys ) - in_txn = self.in_transaction? - self.snapshot unless in_txn - - return keys.each_with_object( [] ) do |key, acc| - acc << self[ key ] + return self.conditional_snapshot do + keys.each_with_object( [] ) do |key, acc| + acc << self[ key ] + end end - ensure - self.abort unless in_txn end @@ -347,5 +329,23 @@ class MDBX::Database return stats end + + ######### + protected + ######### + + ### Yield and return the block, opening a snapshot first if + ### there isn't already a transaction in progress. Closes + ### the snapshot if this method opened it. + ### + def conditional_snapshot + in_txn = self.in_transaction? + self.snapshot unless in_txn + + return yield + ensure + self.abort unless in_txn + end + end # class MDBX::Database diff --git a/spec/mdbx/database_spec.rb b/spec/mdbx/database_spec.rb index 52cafcd..8fb6783 100644 --- a/spec/mdbx/database_spec.rb +++ b/spec/mdbx/database_spec.rb @@ -324,6 +324,7 @@ RSpec.describe( MDBX::Database ) do db.values db.values_at( :woop ) expect( db.in_transaction? ).to be_truthy + db.abort end end