Ruby Berkeley DB
Find a file
2009-11-19 11:13:38 -08:00
ext fix memory allocation error in associate. was causing random DB_SECONDARY_BAD errors if garbage collection reclaimed the space for the secondary key returned by the associate callback 2009-10-16 17:57:12 -07:00
lib/bdb replace Bdb::Simple with Bdb::Database 2009-11-19 11:13:38 -08:00
test fix memory allocation error in associate. was causing random DB_SECONDARY_BAD errors if garbage collection reclaimed the space for the secondary key returned by the associate callback 2009-10-16 17:57:12 -07:00
bdb.gemspec add mutex_set_max 2009-09-21 11:32:38 -07:00
LICENSE Gemification and updated extconf.rb 2008-12-27 20:12:49 -06:00
Rakefile add support for set_btree_compare and multi-key secondary indexes 2009-08-04 18:38:24 -07:00
README.textile update api link 2009-10-02 15:39:34 -07:00

h1. Bdb

Ruby bindings for Berkeley DB versions 4.2-4.7.

h2. Download

Currently this library is available via git at:

<pre>
   git://github.com/mattbauer/bdb.git
</pre>

h2. Installation

h3. From Git

You can check out the latest source from git:

<pre>
   git clone git://github.com/mattbauer/bdb.git
</pre>

h3. As a Gem

At the moment this library is not available on Rubyforge.  To install it as a
gem, do the following (for custom compiled version 4.7):

<pre>
   sudo env ARCHFLAGS="-arch i386" gem install mattbauer-bdb --source http://gems.github.com -- --with-db-dir=/usr/local/BerkeleyDB.4.7
</pre>

For Berkeley DB v4.6 installed from MacPorts do the following:

<pre>
   sudo env ARCHFLAGS="-arch i386" gem install mattbauer-bdb --source http://gems.github.com -- --with-db-include=/opt/local/include/db46 --with-db-lib=/opt/local/lib/db46
</pre>

This assumes you're on OS X and BerkeleyDB wasn't compiled as a universal binary.

h2. Sample Usage

<pre>
  env = Bdb::Env.new(0)
  env_flags =  Bdb::DB_CREATE |    # Create the environment if it does not already exist.
               Bdb::DB_INIT_TXN  | # Initialize transactions
               Bdb::DB_INIT_LOCK | # Initialize locking.
               Bdb::DB_INIT_LOG  | # Initialize logging
               Bdb::DB_INIT_MPOOL  # Initialize the in-memory cache.
  env.open(File.join(File.dirname(__FILE__), 'tmp'), env_flags, 0);
  
  db = env.db
  db.open(nil, 'db1.db', nil, Bdb::Db::BTREE, Bdb::DB_CREATE | Bdb::DB_AUTO_COMMIT, 0)    

  txn = env.txn_begin(nil, 0)
  db.put(txn, 'key', 'value', 0)
  txn.commit(0)

  value = db.get(nil, 'key', nil, 0)

  db.close(0)
  env.close
</pre>

h2. API

This interface is most closely based on the DB4 C api and tries to maintain close 
interface proximity. That API is published by Oracle at "http://www.oracle.com/technology/documentation/berkeley-db/db/api_reference/C/frame_main.html":http://www.oracle.com/technology/documentation/berkeley-db/db/api_reference/C/frame_main.html.

All function arguments systematically omit the leading DB handles and TXN handles.
 A few calls omit the flags parameter when the documentation indicates that no 
 flag values are used - cursor.close is one.

h2. Notes

The defines generator is imperfect and includes some defines that are not
flags. While it could be improved, it is easier to delete the incorrect ones.
Thus, if you decide to rebuild the defines, you will need to edit the resulting
file. This may be necessary if using a different release of DB4 than the ones
the authors developed against.  In nearly every case the defines generator works
flawlessly.

The authors have put all possible caution into ensuring that DB and Ruby cooperate.
The memory access was one aspect carefully considered. Since Ruby copies
when doing String#new, all key/data retrieval from DB is done with a 0 flag,
meaning that DB will be responsible. See "this":http://groups.google.com/group/comp.databases.berkeley-db/browse_frm/thread/4f70a9999b64ce6a/c06b94692e3cbc41?tvc=1&q=dbt+malloc#c06b94692e3cbc41
 news group posting about the effect of that.

The only other design consideration of consequence was associate. The prior
version used a Ruby thread local variable and kept track of the current
database in use. The authors decided to take a simpler approach since Ruby is green
threads. A global array stores the VALUE of the Proc for a given association
by the file descriptor number of the underlying database. This is looked
up when the first layer callback is made. It would have been better considered
if DB allowed the passing of a (void *) user data into the alloc that would
be supplied during callback. So far this design has not produced any problems.