Class: MDBX::Database
- Inherits:
-
Data
- Object
- Data
- MDBX::Database
- Defined in:
- lib/mdbx/database.rb,
ext/mdbx_ext/database.c
Overview
The primary class for interacting with an MDBX database.
Instance Attribute Summary collapse
-
#deserializer ⇒ Object
A Proc for automatically deserializing values.
-
#options ⇒ Object
readonly
Options used when instantiating this database handle.
-
#path ⇒ Object
readonly
The path on disk of the database.
-
#serializer ⇒ Object
A Proc for automatically serializing values.
Class Method Summary collapse
-
.open(*args, &block) ⇒ Object
call-seq: MDBX::Database.open( path ) => db MDBX::Database.open( path, options ) => db.
Instance Method Summary collapse
-
#[]('key') ⇒ Object
Return a single value for
keyimmediately. -
#[]=('key') ⇒ Object
Set a single value for
key. -
#clear ⇒ Object
Empty the current collection on disk.
-
#close ⇒ Object
Cleanly close an opened database.
-
#closed? ⇒ false
Predicate: return true if the database environment is closed.
-
#collection(name = nil) ⇒ Object
(also: #namespace)
Gets or sets the sub-database “collection” that read/write operations apply to.
-
#commit ⇒ Object
(also: #save)
Close any open transaction, writing all changes.
-
#delete(key, &block) ⇒ Object
Deletes the entry for the given key and returns its associated value.
-
#drop(collection) ⇒ Object
Destroy a collection.
-
#each_key {|key| ... } ⇒ self
Calls the block once for each key, returning self.
-
#each_pair {|key, value| ... } ⇒ self
(also: #each)
Calls the block once for each key and value, returning self.
-
#each_value {|value| ... } ⇒ self
Calls the block once for each value, returning self.
-
#empty? ⇒ Boolean
Returns
trueif the current collection has no data. -
#fetch(key, &block) ⇒ Object
Returns the value for the given key, if found.
-
#in_transaction? ⇒ false
Predicate: return true if a transaction (or snapshot) is currently open.
-
#include?('key') ⇒ Boolean
(also: #has_key?)
Returns true if the current collection contains
key. -
#keys ⇒ Object
Returns a new Array containing all keys in the collection.
-
#length ⇒ Integer
(also: #size)
Returns the count of keys in the currently selected collection.
-
#main ⇒ Object
Switch to the top-level collection.
-
#reopen ⇒ Object
Open the DB environment handle.
-
#rollback ⇒ Object
(also: #abort)
Close any open transaction, abandoning all changes.
-
#slice(*keys) ⇒ Object
Returns a new Hash object containing the entries for the given keys.
-
#snapshot(&block) ⇒ Object
Open a new mdbx read only snapshot.
-
#statistics ⇒ Object
Return a hash of various metadata for the current database.
-
#to_a ⇒ Object
Return the entirety of database contents as an Array of array pairs.
-
#to_h ⇒ Object
Return the entirety of database contents as a Hash.
-
#transaction(commit: true, &block) ⇒ Object
Open a new mdbx read/write transaction.
-
#values ⇒ Object
Returns a new Array containing all values in the collection.
-
#values_at(*keys) ⇒ Object
Returns a new Array containing values for the given
keys.
Instance Attribute Details
#deserializer ⇒ Object
A Proc for automatically deserializing values. Defaults to Marshal.load.
128 129 130 |
# File 'lib/mdbx/database.rb', line 128 def deserializer @deserializer end |
#options ⇒ Object (readonly)
Options used when instantiating this database handle.
117 118 119 |
# File 'lib/mdbx/database.rb', line 117 def end |
#path ⇒ Object (readonly)
The path on disk of the database.
120 121 122 |
# File 'lib/mdbx/database.rb', line 120 def path @path end |
#serializer ⇒ Object
A Proc for automatically serializing values. Defaults to Marshal.dump.
124 125 126 |
# File 'lib/mdbx/database.rb', line 124 def serializer @serializer end |
Class Method Details
.open(*args, &block) ⇒ Object
call-seq:
MDBX::Database.open( path ) => db
MDBX::Database.open( path, ) => db
Open an existing (or create a new) mdbx database at filesystem path. In block form, the database is automatically closed when the block exits.
MDBX::Database.open( path, ) do |db|
db[ 'key' ] = value
end # closed!
Passing options modify various database behaviors. See the libmdbx documentation for detailed information.
Options
Unless otherwise mentioned, option keys are symbols, and values are boolean.
- :mode
-
Whe creating a new database, set permissions to this 4 digit octal number. Defaults to ‘0644`. Set to `0` to never automatically create a new file, only opening existing databases.
- :max_collections
-
Set the maximum number of “subdatabase” collections allowed. By default, collection support is disabled.
- :max_readers
-
Set the maximum number of allocated simultaneous reader slots.
- :max_size
-
Set an upper boundary (in bytes) for the database map size. The default is 10485760 bytes.
- :nosubdir
-
When creating a new database, don’t put the data and lock file under a dedicated subdirectory.
- :readonly
-
Reject any write attempts while using this database handle.
- :exclusive
-
Access is restricted to the first opening process. Other attempts to use this database (even in readonly mode) are denied.
- :compat
-
Skip compatibility checks when opening an in-use database with unknown or mismatched flag values.
- :writemap
-
Trade safety for speed for databases that fit within available memory. (See MDBX documentation for details.)
- :no_threadlocal
-
Parallelize read-only transactions across threads. Writes are always thread local. (See MDBX documentatoin for details.)
- :no_readahead
-
Disable all use of OS readahead. Potentially useful for random reads wunder low memory conditions. Default behavior is to dynamically choose when to use or omit readahead.
- :no_memory_init
-
Skip initializing malloc’ed memory to zeroes before writing.
- :coalesce
-
Attempt to coalesce items for the garbage collector, potentialy increasing the chance of unallocating storage earlier.
- :lifo_reclaim
-
Recycle garbage collected items via LIFO, instead of FIFO. Depending on underlying hardware (disk write-back cache), this could increase write performance.
- :no_metasync
-
A system crash may sacrifice the last commit for a potentially large write performance increase. Database integrity is maintained.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/mdbx/database.rb', line 94 def self::open( *args, &block ) db = new( *args ) db.serializer = ->( v ) { Marshal.dump( v ) } db.deserializer = ->( v ) { Marshal.load( v ) } if block_given? begin yield db ensure db.close end end return db end |
Instance Method Details
#[]('key') ⇒ Object
Return a single value for key immediately.
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 |
# File 'ext/mdbx_ext/database.c', line 607 VALUE rmdbx_get_val( VALUE self, VALUE key ) { int rc; UNWRAP_DB( self, db ); CHECK_HANDLE; rmdbx_open_txn( db, MDBX_TXN_RDONLY ); MDBX_val ckey = rmdbx_key_for( key ); MDBX_val data; VALUE rv; rc = mdbx_get( db->txn, db->dbi, &ckey, &data ); rmdbx_close_txn( db, RMDBX_TXN_ROLLBACK ); switch ( rc ) { case MDBX_SUCCESS: rv = rb_str_new( data.iov_base, data.iov_len ); return rmdbx_deserialize( self, rv ); case MDBX_NOTFOUND: return Qnil; default: rmdbx_close( self ); rb_raise( rmdbx_eDatabaseError, "Unable to fetch value: (%d) %s", rc, mdbx_strerror(rc) ); } } |
#[]=('key') ⇒ Object
Set a single value for key. If the value is nil, the key is removed.
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 |
# File 'ext/mdbx_ext/database.c', line 643 VALUE rmdbx_put_val( VALUE self, VALUE key, VALUE val ) { int rc; UNWRAP_DB( self, db ); CHECK_HANDLE; rmdbx_open_txn( db, MDBX_TXN_READWRITE ); MDBX_val ckey = rmdbx_key_for( key ); // FIXME: DUPSORT is enabled -- different api? // See: MDBX_NODUPDATA / MDBX_NOOVERWRITE if ( NIL_P(val) ) { /* remove if set to nil */ rc = mdbx_del( db->txn, db->dbi, &ckey, NULL ); } else { MDBX_val old; MDBX_val data = rmdbx_val_for( self, val ); rc = mdbx_replace( db->txn, db->dbi, &ckey, &data, &old, 0 ); } rmdbx_close_txn( db, RMDBX_TXN_COMMIT ); switch ( rc ) { case MDBX_SUCCESS: return val; case MDBX_NOTFOUND: return Qnil; default: rb_raise( rmdbx_eDatabaseError, "Unable to store value: (%d) %s", rc, mdbx_strerror(rc) ); } } |
#clear ⇒ Object
Empty the current collection on disk. If collections are not enabled or the database handle is set to the top-level (main) db - this deletes *all records* from the database.
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 |
# File 'ext/mdbx_ext/database.c', line 282 VALUE rmdbx_clear( VALUE self ) { UNWRAP_DB( self, db ); rmdbx_open_txn( db, MDBX_TXN_READWRITE ); int rc = mdbx_drop( db->txn, db->dbi, false ); if ( rc != MDBX_SUCCESS ) rb_raise( rmdbx_eDatabaseError, "mdbx_drop: (%d) %s", rc, mdbx_strerror(rc) ); rmdbx_close_txn( db, RMDBX_TXN_COMMIT ); return Qnil; } |
#close ⇒ Object
Cleanly close an opened database.
83 84 85 86 87 88 89 |
# File 'ext/mdbx_ext/database.c', line 83 VALUE rmdbx_close( VALUE self ) { UNWRAP_DB( self, db ); rmdbx_close_all( db ); return Qtrue; } |
#closed? ⇒ false
Predicate: return true if the database environment is closed.
98 99 100 101 102 103 |
# File 'ext/mdbx_ext/database.c', line 98 VALUE rmdbx_closed_p( VALUE self ) { UNWRAP_DB( self, db ); return db->state.open == 1 ? Qfalse : Qtrue; } |
#collection(name = nil) ⇒ Object Also known as: namespace
Gets or sets the sub-database “collection” that read/write operations apply to. If a block is passed, the collection automatically reverts to the prior collection when it exits.
db.collection #=> (collection name, or nil if in main)
db.collection( 'collection_name' ) #=> db
db.collection( 'collection_name' ) do
[ ... ]
end # reverts to the previous collection name
147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/mdbx/database.rb', line 147 def collection( name=nil ) current = self.get_subdb return current unless name self.set_subdb( name.to_s ) yield( self ) if block_given? return self ensure self.set_subdb( current ) if name && block_given? end |
#commit ⇒ Object Also known as: save
Close any open transaction, writing all changes.
217 218 219 |
# File 'lib/mdbx/database.rb', line 217 def commit return self.close_transaction( true ) end |
#delete(key, &block) ⇒ Object
Deletes the entry for the given key and returns its associated value. If no block is given and key is found, deletes the entry and returns the associated value. If no block given and key is not found, returns nil.
If a block is given and key is found, ignores the block, deletes the entry, and returns the associated value. If a block is given and key is not found, calls the block and returns the block’s return value.
279 280 281 282 283 284 285 |
# File 'lib/mdbx/database.rb', line 279 def delete( key, &block ) val = self[ key ] return block.call( key ) if block_given? && val.nil? self[ key ] = nil return val end |
#drop(collection) ⇒ Object
Destroy a collection. You must be in the top level database to call this method.
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
# File 'ext/mdbx_ext/database.c', line 306 VALUE rmdbx_drop( VALUE self, VALUE name ) { UNWRAP_DB( self, db ); /* Provide a friendlier error message if max_collections is 0. */ if ( db->settings.max_collections == 0 ) rb_raise( rmdbx_eDatabaseError, "Unable to drop collection: collections are not enabled." ); /* All transactions must be closed when dropping a database. */ if ( db->txn ) rb_raise( rmdbx_eDatabaseError, "Unable to drop collection: transaction open" ); /* A drop can only be performed from the top-level database. */ if ( db->subdb != NULL ) rb_raise( rmdbx_eDatabaseError, "Unable to drop collection: switch to top-level db first" ); name = rb_funcall( name, rb_intern("to_s"), 0 ); db->subdb = StringValueCStr( name ); rmdbx_close_dbi( db ); /* ensure we're reopening within the new subdb */ rmdbx_open_txn( db, MDBX_TXN_READWRITE ); int rc = mdbx_drop( db->txn, db->dbi, true ); if ( rc != MDBX_SUCCESS ) rb_raise( rmdbx_eDatabaseError, "mdbx_drop: (%d) %s", rc, mdbx_strerror(rc) ); rmdbx_close_txn( db, RMDBX_TXN_COMMIT ); /* Reset the current collection to the top level. */ db->subdb = NULL; rmdbx_close_dbi( db ); /* ensure next access is not in the defunct subdb */ return self; } |
#each_key {|key| ... } ⇒ self
Calls the block once for each key, returning self. A transaction must be opened prior to use.
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 |
# File 'ext/mdbx_ext/database.c', line 422 VALUE rmdbx_each_key( VALUE self ) { UNWRAP_DB( self, db ); int state; CHECK_HANDLE; rmdbx_open_cursor( db ); RETURN_ENUMERATOR( self, 0, 0 ); rb_protect( rmdbx_each_key_i, self, &state ); mdbx_cursor_close( db->cursor ); db->cursor = NULL; if ( state ) rb_jump_tag( state ); return self; } |
#each_pair {|key, value| ... } ⇒ self Also known as: each
Calls the block once for each key and value, returning self. A transaction must be opened prior to use.
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 |
# File 'ext/mdbx_ext/database.c', line 522 VALUE rmdbx_each_pair( VALUE self ) { UNWRAP_DB( self, db ); int state; CHECK_HANDLE; rmdbx_open_cursor( db ); RETURN_ENUMERATOR( self, 0, 0 ); rb_protect( rmdbx_each_pair_i, self, &state ); mdbx_cursor_close( db->cursor ); db->cursor = NULL; if ( state ) rb_jump_tag( state ); return self; } |
#each_value {|value| ... } ⇒ self
Calls the block once for each value, returning self. A transaction must be opened prior to use.
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 |
# File 'ext/mdbx_ext/database.c', line 471 VALUE rmdbx_each_value( VALUE self ) { UNWRAP_DB( self, db ); int state; CHECK_HANDLE; rmdbx_open_cursor( db ); RETURN_ENUMERATOR( self, 0, 0 ); rb_protect( rmdbx_each_value_i, self, &state ); mdbx_cursor_close( db->cursor ); db->cursor = NULL; if ( state ) rb_jump_tag( state ); return self; } |
#empty? ⇒ Boolean
Returns true if the current collection has no data.
248 249 250 |
# File 'lib/mdbx/database.rb', line 248 def empty? return self.size.zero? end |
#fetch(key, &block) ⇒ Object
Returns the value for the given key, if found. If key is not found and no block was given, returns nil. If key is not found and a block was given, yields key to the block and returns the block’s return value.
258 259 260 261 262 263 264 265 266 |
# File 'lib/mdbx/database.rb', line 258 def fetch( key, &block ) val = self[ key ] if block_given? return block.call( key ) if val.nil? else return val if val raise KeyError, "key not found: %p" % [ key ] end end |
#in_transaction? ⇒ false
Predicate: return true if a transaction (or snapshot) is currently open.
113 114 115 116 117 118 |
# File 'ext/mdbx_ext/database.c', line 113 VALUE rmdbx_in_transaction_p( VALUE self ) { UNWRAP_DB( self, db ); return db->txn ? Qtrue : Qfalse; } |
#include?('key') ⇒ Boolean Also known as: has_key?
Returns true if the current collection contains key.
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 |
# File 'ext/mdbx_ext/database.c', line 574 VALUE rmdbx_include( VALUE self, VALUE key ) { int rc; UNWRAP_DB( self, db ); CHECK_HANDLE; rmdbx_open_txn( db, MDBX_TXN_RDONLY ); MDBX_val ckey = rmdbx_key_for( key ); MDBX_val data; rc = mdbx_get( db->txn, db->dbi, &ckey, &data ); rmdbx_close_txn( db, RMDBX_TXN_ROLLBACK ); switch ( rc ) { case MDBX_SUCCESS: return Qtrue; case MDBX_NOTFOUND: return Qfalse; default: rmdbx_close( self ); rb_raise( rmdbx_eDatabaseError, "Unable to fetch key: (%d) %s", rc, mdbx_strerror(rc) ); } } |
#keys ⇒ Object
Returns a new Array containing all keys in the collection.
290 291 292 293 294 |
# File 'lib/mdbx/database.rb', line 290 def keys return self.conditional_snapshot do self.each_key.to_a end end |
#length ⇒ Integer Also known as: size
Returns the count of keys in the currently selected collection.
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
# File 'ext/mdbx_ext/database.c', line 549 VALUE rmdbx_length( VALUE self ) { UNWRAP_DB( self, db ); MDBX_stat mstat; CHECK_HANDLE; rmdbx_open_txn( db, MDBX_TXN_RDONLY ); int rc = mdbx_dbi_stat( db->txn, db->dbi, &mstat, sizeof(mstat) ); if ( rc != MDBX_SUCCESS ) rb_raise( rmdbx_eDatabaseError, "mdbx_dbi_stat: (%d) %s", rc, mdbx_strerror(rc) ); VALUE rv = LONG2FIX( mstat.ms_entries ); rmdbx_close_txn( db, RMDBX_TXN_ROLLBACK ); return rv; } |
#main ⇒ Object
Switch to the top-level collection.
164 165 166 |
# File 'lib/mdbx/database.rb', line 164 def main return self.set_subdb( nil ) end |
#reopen ⇒ Object
Open the DB environment handle.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'ext/mdbx_ext/database.c', line 125 VALUE rmdbx_open_env( VALUE self ) { int rc; UNWRAP_DB( self, db ); rmdbx_close_all( db ); /* Allocate an mdbx environment. */ rc = mdbx_env_create( &db->env ); if ( rc != MDBX_SUCCESS ) rb_raise( rmdbx_eDatabaseError, "mdbx_env_create: (%d) %s", rc, mdbx_strerror(rc) ); /* Set the maximum number of named databases for the environment. */ mdbx_env_set_maxdbs( db->env, db->settings.max_collections ); /* Customize the maximum number of simultaneous readers. */ if ( db->settings.max_readers ) mdbx_env_set_maxreaders( db->env, db->settings.max_readers ); /* Set an upper boundary (in bytes) for the database map size. */ if ( db->settings.max_size ) mdbx_env_set_geometry( db->env, -1, -1, db->settings.max_size, -1, -1, -1 ); rc = mdbx_env_open( db->env, db->path, db->settings.env_flags, db->settings.mode ); if ( rc != MDBX_SUCCESS ) { rmdbx_close_all( db ); rb_raise( rmdbx_eDatabaseError, "mdbx_env_open: (%d) %s", rc, mdbx_strerror(rc) ); } db->state.open = 1; return Qtrue; } |
#rollback ⇒ Object Also known as: abort
Close any open transaction, abandoning all changes.
209 210 211 |
# File 'lib/mdbx/database.rb', line 209 def rollback return self.close_transaction( false ) end |
#slice(*keys) ⇒ Object
Returns a new Hash object containing the entries for the given keys. Any given keys that are not found are ignored.
300 301 302 303 304 305 306 307 |
# File 'lib/mdbx/database.rb', line 300 def slice( *keys ) return self.conditional_snapshot do keys.each_with_object( {} ) do |key, acc| val = self[ key ] acc[ key ] = val if val end end end |
#snapshot(&block) ⇒ Object
Open a new mdbx read only snapshot. In block form, the snapshot is automatically closed when the block ends.
202 203 204 |
# File 'lib/mdbx/database.rb', line 202 def snapshot( &block ) self.transaction( commit: false, &block ) end |
#statistics ⇒ Object
Return a hash of various metadata for the current database.
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 |
# File 'lib/mdbx/database.rb', line 336 def statistics raw = self.raw_stats # Place build options in their own hash. # build_opts = raw.delete( :build_options ).split.each_with_object( {} ) do |opt, acc| key, val = opt.split( '=' ) acc[ key.to_sym ] = Integer( val ) rescue val end stats = { build: { compiler: raw.delete( :build_compiler ), flags: raw.delete( :build_flags ), options: build_opts, target: raw.delete( :build_target ) } } stats.merge!( raw ) return stats end |
#to_a ⇒ Object
Return the entirety of database contents as an Array of array pairs.
230 231 232 233 234 |
# File 'lib/mdbx/database.rb', line 230 def to_a return self.conditional_snapshot do self.each_pair.to_a end end |
#to_h ⇒ Object
Return the entirety of database contents as a Hash.
239 240 241 242 243 |
# File 'lib/mdbx/database.rb', line 239 def to_h return self.conditional_snapshot do self.each_pair.to_h end end |
#transaction(commit: true, &block) ⇒ Object
Open a new mdbx read/write transaction. In block form, the transaction is automatically committed when the block ends.
Raising a MDBX::Rollback exception from within the block automatically rolls the transaction back.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/mdbx/database.rb', line 179 def transaction( commit: true, &block ) self.open_transaction( commit ) yield self if block_given? return self rescue MDBX::Rollback commit = false self.rollback rescue commit = false self.rollback raise ensure if block_given? commit ? self.commit : self.rollback end end |
#values ⇒ Object
Returns a new Array containing all values in the collection.
312 313 314 315 316 |
# File 'lib/mdbx/database.rb', line 312 def values return self.conditional_snapshot do self.each_value.to_a end end |
#values_at(*keys) ⇒ Object
Returns a new Array containing values for the given keys.
321 322 323 324 325 326 327 |
# File 'lib/mdbx/database.rb', line 321 def values_at( *keys ) return self.conditional_snapshot do keys.each_with_object( [] ) do |key, acc| acc << self[ key ] end end end |