home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / perl502b.zip / lib / DB_File.pm < prev    next >
Text File  |  1995-07-03  |  15KB  |  580 lines

  1. # DB_File.pm -- Perl 5 interface to Berkeley DB 
  2. #
  3. # written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
  4. # last modified 19th May 1995
  5. # version 0.2
  6.  
  7. =head1 NAME
  8.  
  9. DB_File - Perl5 access to Berkeley DB
  10.  
  11. =head1 SYNOPSIS
  12.  
  13.  use DB_File ;
  14.   
  15.  [$X =] tie %hash,  DB_File, $filename [, $flags, $mode, $DB_HASH] ;
  16.  [$X =] tie %hash,  DB_File, $filename, $flags, $mode, $DB_BTREE ;
  17.  [$X =] tie @array, DB_File, $filename, $flags, $mode, $DB_RECNO ;
  18.    
  19.  $status = $X->del($key [, $flags]) ;
  20.  $status = $X->put($key, $value [, $flags]) ;
  21.  $status = $X->get($key, $value [, $flags]) ;
  22.  $status = $X->seq($key, $value [, $flags]) ;
  23.  $status = $X->sync([$flags]) ;
  24.  $status = $X->fd ;
  25.     
  26.  untie %hash ;
  27.  untie @array ;
  28.  
  29. =head1 DESCRIPTION
  30.  
  31. B<DB_File> is a module which allows Perl programs to make use of 
  32. the facilities provided by Berkeley DB.  If you intend to use this
  33. module you should really have a copy of the Berkeley DB manual
  34. page at hand. The interface defined here
  35. mirrors the Berkeley DB interface closely.
  36.  
  37. Berkeley DB is a C library which provides a consistent interface to a number of 
  38. database formats. 
  39. B<DB_File> provides an interface to all three of the database types currently
  40. supported by Berkeley DB.
  41.  
  42. The file types are:
  43.  
  44. =over 5
  45.  
  46. =item DB_HASH
  47.  
  48. This database type allows arbitrary key/data pairs to be stored in data files.
  49. This is equivalent to the functionality provided by 
  50. other hashing packages like DBM, NDBM, ODBM, GDBM, and SDBM.
  51. Remember though, the files created using DB_HASH are 
  52. not compatible with any of the other packages mentioned.
  53.  
  54. A default hashing algorithm, which will be adequate for most applications, 
  55. is built into Berkeley DB.  
  56. If you do need to use your own hashing algorithm it is possible to write your
  57. own in Perl and have B<DB_File> use it instead.
  58.  
  59. =item DB_BTREE
  60.  
  61. The btree format allows arbitrary key/data pairs to be stored in a sorted, 
  62. balanced binary tree.
  63.  
  64. As with the DB_HASH format, it is possible to provide a user defined Perl routine
  65. to perform the comparison of keys. By default, though, the keys are stored 
  66. in lexical order.
  67.  
  68. =item DB_RECNO
  69.  
  70. DB_RECNO allows both fixed-length and variable-length flat text files to be 
  71. manipulated using 
  72. the same key/value pair interface as in DB_HASH and DB_BTREE. 
  73. In this case the key will consist of a record (line) number. 
  74.  
  75. =back
  76.  
  77. =head2 How does DB_File interface to Berkeley DB?
  78.  
  79. B<DB_File> allows access to Berkeley DB files using the tie() mechanism
  80. in Perl 5 (for full details, see L<perlfunc/tie()>).
  81. This facility allows B<DB_File> to access Berkeley DB files using
  82. either an associative array (for DB_HASH & DB_BTREE file types) or an
  83. ordinary array (for the DB_RECNO file type).
  84.  
  85. In addition to the tie() interface, it is also possible to use most of the
  86. functions provided in the Berkeley DB API.
  87.  
  88. =head2 Differences with Berkeley DB
  89.  
  90. Berkeley DB uses the function dbopen() to open or create a 
  91. database. Below is the C prototype for dbopen().
  92.  
  93.       DB*
  94.       dbopen (const char * file, int flags, int mode, 
  95.               DBTYPE type, const void * openinfo)
  96.  
  97. The parameter C<type> is an enumeration which specifies which of the 3
  98. interface methods (DB_HASH, DB_BTREE or DB_RECNO) is to be used.
  99. Depending on which of these is actually chosen, the final parameter,
  100. I<openinfo> points to a data structure which allows tailoring of the
  101. specific interface method.
  102.  
  103. This interface is handled 
  104. slightly differently in B<DB_File>. Here is an equivalent call using
  105. B<DB_File>.
  106.  
  107.         tie %array, DB_File, $filename, $flags, $mode, $DB_HASH ;
  108.  
  109. The C<filename>, C<flags> and C<mode> parameters are the direct equivalent 
  110. of their dbopen() counterparts. The final parameter $DB_HASH
  111. performs the function of both the C<type> and C<openinfo>
  112. parameters in dbopen().
  113.  
  114. In the example above $DB_HASH is actually a reference to a hash object.
  115. B<DB_File> has three of these pre-defined references.
  116. Apart from $DB_HASH, there is also $DB_BTREE and $DB_RECNO.
  117.  
  118. The keys allowed in each of these pre-defined references is limited to the names
  119. used in the equivalent C structure.
  120. So, for example, the $DB_HASH reference will only allow keys called C<bsize>,
  121. C<cachesize>, C<ffactor>, C<hash>, C<lorder> and C<nelem>. 
  122.  
  123. To change one of these elements, just assign to it like this
  124.  
  125.     $DB_HASH{cachesize} = 10000 ;
  126.  
  127.  
  128. =head2 RECNO
  129.  
  130.  
  131. In order to make RECNO more compatible with Perl the array offset for all
  132. RECNO arrays begins at 0 rather than 1 as in Berkeley DB.
  133.  
  134.  
  135. =head2 In Memory Databases
  136.  
  137. Berkeley DB allows the creation of in-memory databases by using NULL (that is, a 
  138. C<(char *)0 in C) in 
  139. place of the filename. 
  140. B<DB_File> uses C<undef> instead of NULL to provide this functionality.
  141.  
  142.  
  143. =head2 Using the Berkeley DB Interface Directly
  144.  
  145. As well as accessing Berkeley DB using a tied hash or array, it is also
  146. possible to make direct use of most of the functions defined in the Berkeley DB
  147. documentation.
  148.  
  149.  
  150. To do this you need to remember the return value from the tie.
  151.  
  152.     $db = tie %hash, DB_File, "filename"
  153.  
  154. Once you have done that, you can access the Berkeley DB API functions directly.
  155.  
  156.     $db->put($key, $value, R_NOOVERWRITE) ;
  157.  
  158. All the functions defined in L<dbx(3X)> are available except
  159. for close() and dbopen() itself.  
  160. The B<DB_File> interface to these functions have been implemented to mirror
  161. the the way Berkeley DB works. In particular note that all the functions return
  162. only a status value. Whenever a Berkeley DB function returns data via one of
  163. its parameters, the B<DB_File> equivalent does exactly the same.
  164.  
  165. All the constants defined in L<dbopen> are also available.
  166.  
  167. Below is a list of the functions available.
  168.  
  169. =over 5
  170.  
  171. =item get
  172.  
  173. Same as in C<recno> except that the flags parameter is optional. 
  174. Remember the value
  175. associated with the key you request is returned in the $value parameter.
  176.  
  177. =item put
  178.  
  179. As usual the flags parameter is optional. 
  180.  
  181. If you use either the R_IAFTER or
  182. R_IBEFORE flags, the key parameter will have the record number of the inserted
  183. key/value pair set.
  184.  
  185. =item del
  186.  
  187. The flags parameter is optional.
  188.  
  189. =item fd
  190.  
  191. As in I<recno>.
  192.  
  193. =item seq
  194.  
  195. The flags parameter is optional.
  196.  
  197. Both the key and value parameters will be set.
  198.  
  199. =item sync
  200.  
  201. The flags parameter is optional.
  202.  
  203. =back
  204.  
  205. =head1 EXAMPLES
  206.  
  207. It is always a lot easier to understand something when you see a real example.
  208. So here are a few.
  209.  
  210. =head2 Using HASH
  211.  
  212.     use DB_File ;
  213.     use Fcntl ;
  214.     
  215.     tie %h,  DB_File, "hashed", O_RDWR|O_CREAT, 0640, $DB_HASH ;
  216.     
  217.     # Add a key/value pair to the file
  218.     $h{"apple"} = "orange" ;
  219.     
  220.     # Check for existence of a key
  221.     print "Exists\n" if $h{"banana"} ;
  222.     
  223.     # Delete 
  224.     delete $h{"apple"} ;
  225.     
  226.     untie %h ;
  227.  
  228. =head2 Using BTREE
  229.  
  230. Here is sample of code which used BTREE. Just to make life more interesting
  231. the default comparision function will not be used. Instead a Perl sub, C<Compare()>,
  232. will be used to do a case insensitive comparison.
  233.  
  234.         use DB_File ;
  235.         use Fcntl ;
  236.      
  237.     sub Compare
  238.         {
  239.         my ($key1, $key2) = @_ ;
  240.     
  241.         "\L$key1" cmp "\L$key2" ;
  242.     }
  243.     
  244.         $DB_BTREE->{compare} = 'Compare' ;
  245.      
  246.         tie %h,  DB_File, "tree", O_RDWR|O_CREAT, 0640, $DB_BTREE ;
  247.      
  248.         # Add a key/value pair to the file
  249.         $h{'Wall'} = 'Larry' ;
  250.         $h{'Smith'} = 'John' ;
  251.     $h{'mouse'} = 'mickey' ;
  252.     $h{'duck'}   = 'donald' ;
  253.      
  254.         # Delete
  255.         delete $h{"duck"} ;
  256.      
  257.     # Cycle through the keys printing them in order.
  258.     # Note it is not necessary to sort the keys as
  259.     # the btree will have kept them in order automatically.
  260.     foreach (keys %h)
  261.       { print "$_\n" }
  262.     
  263.         untie %h ;
  264.  
  265. Here is the output from the code above.
  266.  
  267.     mouse
  268.     Smith
  269.     Wall
  270.  
  271.  
  272. =head2 Using RECNO
  273.  
  274.     use DB_File ;
  275.     use Fcntl ;
  276.     
  277.     $DB_RECNO->{psize} = 3000 ;
  278.     
  279.     tie @h,  DB_File, "text", O_RDWR|O_CREAT, 0640, $DB_RECNO ;
  280.     
  281.     # Add a key/value pair to the file
  282.     $h[0] = "orange" ;
  283.     
  284.     # Check for existence of a key
  285.     print "Exists\n" if $h[1] ;
  286.     
  287.     untie @h ;
  288.  
  289.  
  290.  
  291. =head1 CHANGES
  292.  
  293. =head2 0.1
  294.  
  295. First Release.
  296.  
  297. =head2 0.2
  298.  
  299. When B<DB_File> is opening a database file it no longer terminates the
  300. process if I<dbopen> returned an error. This allows file protection
  301. errors to be caught at run time. Thanks to Judith Grass
  302. <grass@cybercash.com> for spotting the bug.
  303.  
  304. =head1 WARNINGS
  305.  
  306. If you happen find any other functions defined in the source for this module 
  307. that have not been mentioned in this document -- beware. 
  308. I may drop them at a moments notice.
  309.  
  310. If you cannot find any, then either you didn't look very hard or the moment has
  311. passed and I have dropped them.
  312.  
  313. =head1 BUGS
  314.  
  315. Some older versions of Berkeley DB had problems with fixed length records
  316. using the RECNO file format. The newest version at the time of writing 
  317. was 1.85 - this seems to have fixed the problems with RECNO.
  318.  
  319. I am sure there are bugs in the code. If you do find any, or can suggest any
  320. enhancements, I would welcome your comments.
  321.  
  322. =head1 AVAILABILITY
  323.  
  324. Berkeley DB is available via the hold C<ftp.cs.berkeley.edu> in the
  325. directory C</ucb/4bsd/db.tar.gz>.  It is I<not> under the GPL.
  326.  
  327. =head1 SEE ALSO
  328.  
  329. L<perl(1)>, L<dbopen(3)>, L<hash(3)>, L<recno(3)>, L<btree(3)> 
  330.  
  331. Berkeley DB is available from F<ftp.cs.berkeley.edu> in the directory F</ucb/4bsd>.
  332.  
  333. =head1 AUTHOR
  334.  
  335. The DB_File interface was written by 
  336. Paul Marquess <pmarquess@bfsec.bt.co.uk>.
  337. Questions about the DB system itself may be addressed to
  338. Keith Bostic  <bostic@cs.berkeley.edu>.
  339.  
  340. =cut
  341.  
  342. package DB_File::HASHINFO ;
  343. use Carp;
  344.  
  345. sub TIEHASH
  346. {
  347.     bless {} ;
  348. }
  349.  
  350. %elements = ( 'bsize'     => 0,
  351.               'ffactor'   => 0,
  352.               'nelem'     => 0,
  353.               'cachesize' => 0,
  354.               'hash'      => 0,
  355.               'lorder'    => 0
  356.             ) ;
  357.  
  358. sub FETCH 
  359. {  
  360.     return $_[0]{$_[1]} if defined $elements{$_[1]}  ;
  361.  
  362.     croak "DB_File::HASHINFO::FETCH - Unknown element '$_[1]'" ;
  363. }
  364.  
  365.  
  366. sub STORE 
  367. {
  368.     if ( defined $elements{$_[1]} )
  369.     {
  370.         $_[0]{$_[1]} = $_[2] ;
  371.         return ;
  372.     }
  373.     
  374.     croak "DB_File::HASHINFO::STORE - Unknown element '$_[1]'" ;
  375. }
  376.  
  377. sub DELETE 
  378. {
  379.     if ( defined $elements{$_[1]} )
  380.     {
  381.         delete ${$_[0]}{$_[1]} ;
  382.         return ;
  383.     }
  384.     
  385.     croak "DB_File::HASHINFO::DELETE - Unknown element '$_[1]'" ;
  386. }
  387.  
  388.  
  389. sub DESTROY {undef %{$_[0]} }
  390. sub FIRSTKEY { croak "DB_File::HASHINFO::FIRSTKEY is not implemented" }
  391. sub NEXTKEY { croak "DB_File::HASHINFO::NEXTKEY is not implemented" }
  392. sub EXISTS { croak "DB_File::HASHINFO::EXISTS is not implemented" }
  393. sub CLEAR { croak "DB_File::HASHINFO::CLEAR is not implemented" }
  394.  
  395. package DB_File::BTREEINFO ;
  396. use Carp;
  397.  
  398. sub TIEHASH
  399. {
  400.     bless {} ;
  401. }
  402.  
  403. %elements = ( 'flags'    => 0,
  404.               'cachesize'  => 0,
  405.               'maxkeypage' => 0,
  406.               'minkeypage' => 0,
  407.               'psize'      => 0,
  408.               'compare'    => 0,
  409.               'prefix'     => 0,
  410.               'lorder'     => 0
  411.             ) ;
  412.  
  413. sub FETCH 
  414. {  
  415.     return $_[0]{$_[1]} if defined $elements{$_[1]}  ;
  416.  
  417.     croak "DB_File::BTREEINFO::FETCH - Unknown element '$_[1]'" ;
  418. }
  419.  
  420.  
  421. sub STORE 
  422. {
  423.     if ( defined $elements{$_[1]} )
  424.     {
  425.         $_[0]{$_[1]} = $_[2] ;
  426.         return ;
  427.     }
  428.     
  429.     croak "DB_File::BTREEINFO::STORE - Unknown element '$_[1]'" ;
  430. }
  431.  
  432. sub DELETE 
  433. {
  434.     if ( defined $elements{$_[1]} )
  435.     {
  436.         delete ${$_[0]}{$_[1]} ;
  437.         return ;
  438.     }
  439.     
  440.     croak "DB_File::BTREEINFO::DELETE - Unknown element '$_[1]'" ;
  441. }
  442.  
  443.  
  444. sub DESTROY {undef %{$_[0]} }
  445. sub FIRSTKEY { croak "DB_File::BTREEINFO::FIRSTKEY is not implemented" }
  446. sub NEXTKEY { croak "DB_File::BTREEINFO::NEXTKEY is not implemented" }
  447. sub EXISTS { croak "DB_File::BTREEINFO::EXISTS is not implemented" }
  448. sub CLEAR { croak "DB_File::BTREEINFO::CLEAR is not implemented" }
  449.  
  450. package DB_File::RECNOINFO ;
  451. use Carp;
  452.  
  453. sub TIEHASH
  454. {
  455.     bless {} ;
  456. }
  457.  
  458. %elements = ( 'bval'      => 0,
  459.               'cachesize' => 0,
  460.               'psize'     => 0,
  461.               'flags'     => 0,
  462.               'lorder'    => 0,
  463.               'reclen'    => 0,
  464.               'bfname'    => 0
  465.             ) ;
  466. sub FETCH 
  467. {  
  468.     return $_[0]{$_[1]} if defined $elements{$_[1]}  ;
  469.  
  470.     croak "DB_File::RECNOINFO::FETCH - Unknown element '$_[1]'" ;
  471. }
  472.  
  473.  
  474. sub STORE 
  475. {
  476.     if ( defined $elements{$_[1]} )
  477.     {
  478.         $_[0]{$_[1]} = $_[2] ;
  479.         return ;
  480.     }
  481.     
  482.     croak "DB_File::RECNOINFO::STORE - Unknown element '$_[1]'" ;
  483. }
  484.  
  485. sub DELETE 
  486. {
  487.     if ( defined $elements{$_[1]} )
  488.     {
  489.         delete ${$_[0]}{$_[1]} ;
  490.         return ;
  491.     }
  492.     
  493.     croak "DB_File::RECNOINFO::DELETE - Unknown element '$_[1]'" ;
  494. }
  495.  
  496.  
  497. sub DESTROY {undef %{$_[0]} }
  498. sub FIRSTKEY { croak "DB_File::RECNOINFO::FIRSTKEY is not implemented" }
  499. sub NEXTKEY { croak "DB_File::RECNOINFO::NEXTKEY is not implemented" }
  500. sub EXISTS { croak "DB_File::BTREEINFO::EXISTS is not implemented" }
  501. sub CLEAR { croak "DB_File::BTREEINFO::CLEAR is not implemented" }
  502.  
  503.  
  504.  
  505. package DB_File ;
  506. use Carp;
  507.  
  508. #typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
  509. $DB_BTREE = TIEHASH DB_File::BTREEINFO ;
  510. $DB_HASH  = TIEHASH DB_File::HASHINFO ;
  511. $DB_RECNO = TIEHASH DB_File::RECNOINFO ;
  512.  
  513. require TieHash;
  514. require Exporter;
  515. use AutoLoader;
  516. require DynaLoader;
  517. @ISA = qw(TieHash Exporter DynaLoader);
  518. @EXPORT = qw(
  519.         $DB_BTREE $DB_HASH $DB_RECNO 
  520.     BTREEMAGIC
  521.     BTREEVERSION
  522.     DB_LOCK
  523.     DB_SHMEM
  524.     DB_TXN
  525.     HASHMAGIC
  526.     HASHVERSION
  527.     MAX_PAGE_NUMBER
  528.     MAX_PAGE_OFFSET
  529.     MAX_REC_NUMBER
  530.     RET_ERROR
  531.     RET_SPECIAL
  532.     RET_SUCCESS
  533.     R_CURSOR
  534.     R_DUP
  535.     R_FIRST
  536.     R_FIXEDLEN
  537.     R_IAFTER
  538.     R_IBEFORE
  539.     R_LAST
  540.     R_NEXT
  541.     R_NOKEY
  542.     R_NOOVERWRITE
  543.     R_PREV
  544.     R_RECNOSYNC
  545.     R_SETCURSOR
  546.     R_SNAPSHOT
  547.     __R_UNUSED
  548. );
  549.  
  550. sub AUTOLOAD {
  551.     local($constname);
  552.     ($constname = $AUTOLOAD) =~ s/.*:://;
  553.     $val = constant($constname, @_ ? $_[0] : 0);
  554.     if ($! != 0) {
  555.     if ($! =~ /Invalid/) {
  556.         $AutoLoader::AUTOLOAD = $AUTOLOAD;
  557.         goto &AutoLoader::AUTOLOAD;
  558.     }
  559.     else {
  560.         ($pack,$file,$line) = caller;
  561.         croak "Your vendor has not defined DB macro $constname, used at $file line $line.
  562. ";
  563.     }
  564.     }
  565.     eval "sub $AUTOLOAD { $val }";
  566.     goto &$AUTOLOAD;
  567. }
  568.  
  569. @liblist = ();
  570. @liblist = split ' ', $Config::Config{"DB_File_loadlibs"} 
  571.     if defined $Config::Config{"DB_File_loadlibs"};
  572.  
  573. bootstrap DB_File @liblist;
  574.  
  575. # Preloaded methods go here.  Autoload methods go after __END__, and are
  576. # processed by the autosplit program.
  577.  
  578. 1;
  579. __END__
  580.