Author image Andreas J. König


Tie::MAB2::Dualdb - A BerkeleyDB dual db (both Recno and Hash) for MAB2 records


 tie @tie, 'Tie::MAB2::Dualdb', ...;


A dual db has an array side and a hash side. Pushing a record onto the array triggers the ID of the record and the record number to be inserted into the hash.

One reason why we invent this is to have a compatibility database between the old readonly database that used Tie::MAB2::Recno and seek and tell. We should now be able to use the same record numbers to access the array side of the dual db. And we should be able to have these records in RDWR access and accessible via their ID, as before. The second reason why we have this is the RAND access we liked so much in the web interface.

We're not really sure that this is a necessary interface, but it seems so convenient that we want to try it out even if it's a bit of a waste compared to a pure HASH solution.

The interface throws an exception when records with an already included ID are pushed onto the array.

Dualdb is not a fully functional tied array. It doesn't implement e.g. the STORESIZE and SPLICE methods. The array is limited to PUSH and direct access. CLEAR seems to be broken in BerkeleyDB 0.22, so we do not support it yet. See the source code for outcommented CLEAR methods. They provoked the error message.

  Can't call method "c_get" on an undefined value at /usr/local/perl-5.8.0/lib/sit
  e_perl/5.8.0/i686-linux-multi/ line 1152.

I did try to replace &BerkeleyDB::_tiedHash::CLEAR with something that used truncate():

  sub CLEAR {
      my $self = shift;
      $self->truncate(my $cnt);

, and it worked, but I do not want to mess with BDB internals. Maybe when I calm down.

Note that records cannot be deleted, they must be overwritten instead. There are two ways to do this:

overwrite with a record

overwrite the record with a MAB record that has the Satzstatus (byte 5) set to d. This variant keeps a pointer to the record in the associated ID hash.

overwrite with empty string

overwrite the record with an empty string. This variant removes the pointer in the associated ID hash. Such a table will get sparse over time.


Reading is always done by one of the two accessors Tie::MAB2::Dualdb::Recno or Tie::MAB2::Dualdb::Id, like in

      filename => "export_mab_01.dualdb",
      flags => DB_RDONLY,
     ) or die "Could not tie";

Only writing is done through this module as in

  my $flags = DB_CREATE|DB_INIT_MPOOL;
      filename => $dualdb,
      flags => $flags,
     ) or die "Could not tie";