summaryrefslogtreecommitdiff
path: root/ext/DB_File
diff options
context:
space:
mode:
authorAndy Dougherty <doughera@lafcol.lafayette.edu>1995-10-31 03:33:09 +0000
committerAndy Dougherty <doughera@lafcol.lafayette.edu>1995-10-31 03:33:09 +0000
commit8e07c86ebc651fe92eb7e3b25f801f57cfb8dd6f (patch)
treebd67a65038befe4bef8b330a688bf7d915cab92f /ext/DB_File
parente50aee73b3d4c555c37e4b4a16694765fb16c887 (diff)
downloadperl-8e07c86ebc651fe92eb7e3b25f801f57cfb8dd6f.tar.gz
This is my patch patch.1n for perl5.001.perl-5.001n
To apply, change to your perl directory, run the command above, then apply with patch -p1 -N < thispatch. This is a consolidation patch. It contains many of the most commonly applied or agreed-to patches that have been circulating since patch.1m. It also changes the 'unofficial patchlevel' in perl.c. There are some problems (see items marked with '***'). I will attempt to address those in a patch.1o in a few days. This patch contains the following packages: My Jumbo Configure patch vs. 1m, with subsequent patches 1, 2, and 3. Mainly, this provides easier use of local libraries, documents the installation process in a new INSTALL file, moves important questions towards the beginning, and improves detection of signal names (mostly for Linux). xsubpp-1.922. Patches from Larry: eval "1" memory leak patch (as modified by GSAR to apply to 5.001m). NETaa14551 Infinite loop in formats, NETaa13729 scope.c patch (fixed problems on AIX and others) NETaa14138 "substr() & s///" (pp_hot.c) Patches from ftp.perl.com: ftp://ftp.perl.com/pub/perl/src/patches/closure-bug.patch, version of 20 Sep 1995 Includes fix for NETaa14347 (32k limit in regex), and other fixes. ftp://ftp.perl.com/pub/perl/src/patches/debugger.patch, version of 27 Aug 1995 ftp://ftp.perl.com/pub/perl/src/patches/glob-undef.patch, version of 4 Sep 1995 NETaa14421 $_ doesn't undef ftp://ftp.perl.com/pub/perl/src/patches/op-segfault.patch, version of 21 Aug 1995 ftp://ftp.perl.com/pub/perl/src/patches/warn-ref-hash-key.patch, version of 5 Jun 1995 Tim Bunce's Jumbo DynaLoader patch for Perl5.001m, which is NETaa14636 Jumbo DynaLoader patch for Perl5.001m, and Additional patch for NETaa14636 Jumbo DynaLoader patch for Perl5.001m version of 09 Oct 1995. ***This needs some additional parentheses.*** MakeMaker-5.00. Supercedes NETaa13540 (VMS MakeMaker patches). (Updates minimod.PL as well.) ***This has a couple of minor problems. pod2man is run even if it isn't available. LD_RUN_PATH gets set to some mysterious values.*** NETaa14657 Paul Marquess Net::Ping patch. I've included Net-Ping-1.00. NETaa14661 Dean Roehrich DProf. Installed as ext/Devel/DProf. Configure should pick this up automatically. (5 Apr 1995 version.) NETaa13742 Jack Shirazi Socket in 5.001. I've also included his socket.t test in t/lib/socket.t. c2ph-1.7. Dean's perlapi patches of Oct 12, 1995, which superceded those of Oct 8, 1995. This is the one that did mv perlapi.pid perlxs.pod. NETaa14310 Tim Bunce A trivial patch for configpm (handy for shell scripts) DB_File-1.0 patch from Paul Marquess (pmarquess@bfsec.bt.co.uk) last modified 7th October 1995 version 1.0 Added or updated the following hints files: hints/hpux.sh hints/ncr_tower.sh hints/netbsd.sh hints/ultrix.sh Patch and enjoy. Andy Dougherty doughera@lafcol.lafayette.edu Dept. of Physics Lafayette College, Easton PA 18042
Diffstat (limited to 'ext/DB_File')
-rw-r--r--ext/DB_File/DB_File.pm679
-rw-r--r--ext/DB_File/DB_File.xs170
-rw-r--r--ext/DB_File/Makefile.PL9
-rw-r--r--ext/DB_File/typemap2
4 files changed, 464 insertions, 396 deletions
diff --git a/ext/DB_File/DB_File.pm b/ext/DB_File/DB_File.pm
index 5b9fba7765..0491d6bb42 100644
--- a/ext/DB_File/DB_File.pm
+++ b/ext/DB_File/DB_File.pm
@@ -1,8 +1,251 @@
# DB_File.pm -- Perl 5 interface to Berkeley DB
#
# written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
-# last modified 19th May 1995
-# version 0.2
+# last modified 7th October 1995
+# version 1.0
+
+package DB_File::HASHINFO ;
+use Carp;
+
+sub TIEHASH
+{
+ bless {} ;
+}
+
+%elements = ( 'bsize' => 0,
+ 'ffactor' => 0,
+ 'nelem' => 0,
+ 'cachesize' => 0,
+ 'hash' => 0,
+ 'lorder' => 0
+ ) ;
+
+sub FETCH
+{
+ return $_[0]{$_[1]} if defined $elements{$_[1]} ;
+
+ croak "DB_File::HASHINFO::FETCH - Unknown element '$_[1]'" ;
+}
+
+
+sub STORE
+{
+ if ( defined $elements{$_[1]} )
+ {
+ $_[0]{$_[1]} = $_[2] ;
+ return ;
+ }
+
+ croak "DB_File::HASHINFO::STORE - Unknown element '$_[1]'" ;
+}
+
+sub DELETE
+{
+ if ( defined $elements{$_[1]} )
+ {
+ delete ${$_[0]}{$_[1]} ;
+ return ;
+ }
+
+ croak "DB_File::HASHINFO::DELETE - Unknown element '$_[1]'" ;
+}
+
+
+sub DESTROY {undef %{$_[0]} }
+sub FIRSTKEY { croak "DB_File::HASHINFO::FIRSTKEY is not implemented" }
+sub NEXTKEY { croak "DB_File::HASHINFO::NEXTKEY is not implemented" }
+sub EXISTS { croak "DB_File::HASHINFO::EXISTS is not implemented" }
+sub CLEAR { croak "DB_File::HASHINFO::CLEAR is not implemented" }
+
+package DB_File::BTREEINFO ;
+use Carp;
+
+sub TIEHASH
+{
+ bless {} ;
+}
+
+%elements = ( 'flags' => 0,
+ 'cachesize' => 0,
+ 'maxkeypage' => 0,
+ 'minkeypage' => 0,
+ 'psize' => 0,
+ 'compare' => 0,
+ 'prefix' => 0,
+ 'lorder' => 0
+ ) ;
+
+sub FETCH
+{
+ return $_[0]{$_[1]} if defined $elements{$_[1]} ;
+
+ croak "DB_File::BTREEINFO::FETCH - Unknown element '$_[1]'" ;
+}
+
+
+sub STORE
+{
+ if ( defined $elements{$_[1]} )
+ {
+ $_[0]{$_[1]} = $_[2] ;
+ return ;
+ }
+
+ croak "DB_File::BTREEINFO::STORE - Unknown element '$_[1]'" ;
+}
+
+sub DELETE
+{
+ if ( defined $elements{$_[1]} )
+ {
+ delete ${$_[0]}{$_[1]} ;
+ return ;
+ }
+
+ croak "DB_File::BTREEINFO::DELETE - Unknown element '$_[1]'" ;
+}
+
+
+sub DESTROY {undef %{$_[0]} }
+sub FIRSTKEY { croak "DB_File::BTREEINFO::FIRSTKEY is not implemented" }
+sub NEXTKEY { croak "DB_File::BTREEINFO::NEXTKEY is not implemented" }
+sub EXISTS { croak "DB_File::BTREEINFO::EXISTS is not implemented" }
+sub CLEAR { croak "DB_File::BTREEINFO::CLEAR is not implemented" }
+
+package DB_File::RECNOINFO ;
+use Carp;
+
+sub TIEHASH
+{
+ bless {} ;
+}
+
+%elements = ( 'bval' => 0,
+ 'cachesize' => 0,
+ 'psize' => 0,
+ 'flags' => 0,
+ 'lorder' => 0,
+ 'reclen' => 0,
+ 'bfname' => 0
+ ) ;
+sub FETCH
+{
+ return $_[0]{$_[1]} if defined $elements{$_[1]} ;
+
+ croak "DB_File::RECNOINFO::FETCH - Unknown element '$_[1]'" ;
+}
+
+
+sub STORE
+{
+ if ( defined $elements{$_[1]} )
+ {
+ $_[0]{$_[1]} = $_[2] ;
+ return ;
+ }
+
+ croak "DB_File::RECNOINFO::STORE - Unknown element '$_[1]'" ;
+}
+
+sub DELETE
+{
+ if ( defined $elements{$_[1]} )
+ {
+ delete ${$_[0]}{$_[1]} ;
+ return ;
+ }
+
+ croak "DB_File::RECNOINFO::DELETE - Unknown element '$_[1]'" ;
+}
+
+
+sub DESTROY {undef %{$_[0]} }
+sub FIRSTKEY { croak "DB_File::RECNOINFO::FIRSTKEY is not implemented" }
+sub NEXTKEY { croak "DB_File::RECNOINFO::NEXTKEY is not implemented" }
+sub EXISTS { croak "DB_File::BTREEINFO::EXISTS is not implemented" }
+sub CLEAR { croak "DB_File::BTREEINFO::CLEAR is not implemented" }
+
+
+
+package DB_File ;
+use Carp;
+
+$VERSION = 1.0 ;
+
+#typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
+$DB_BTREE = TIEHASH DB_File::BTREEINFO ;
+$DB_HASH = TIEHASH DB_File::HASHINFO ;
+$DB_RECNO = TIEHASH DB_File::RECNOINFO ;
+
+require TieHash;
+require Exporter;
+use AutoLoader;
+require DynaLoader;
+@ISA = qw(TieHash Exporter DynaLoader);
+@EXPORT = qw(
+ $DB_BTREE $DB_HASH $DB_RECNO
+ BTREEMAGIC
+ BTREEVERSION
+ DB_LOCK
+ DB_SHMEM
+ DB_TXN
+ HASHMAGIC
+ HASHVERSION
+ MAX_PAGE_NUMBER
+ MAX_PAGE_OFFSET
+ MAX_REC_NUMBER
+ RET_ERROR
+ RET_SPECIAL
+ RET_SUCCESS
+ R_CURSOR
+ R_DUP
+ R_FIRST
+ R_FIXEDLEN
+ R_IAFTER
+ R_IBEFORE
+ R_LAST
+ R_NEXT
+ R_NOKEY
+ R_NOOVERWRITE
+ R_PREV
+ R_RECNOSYNC
+ R_SETCURSOR
+ R_SNAPSHOT
+ __R_UNUSED
+);
+
+sub AUTOLOAD {
+ local($constname);
+ ($constname = $AUTOLOAD) =~ s/.*:://;
+ $val = constant($constname, @_ ? $_[0] : 0);
+ if ($! != 0) {
+ if ($! =~ /Invalid/) {
+ $AutoLoader::AUTOLOAD = $AUTOLOAD;
+ goto &AutoLoader::AUTOLOAD;
+ }
+ else {
+ ($pack,$file,$line) = caller;
+ croak "Your vendor has not defined DB macro $constname, used at $file line $line.
+";
+ }
+ }
+ eval "sub $AUTOLOAD { $val }";
+ goto &$AUTOLOAD;
+}
+
+@liblist = ();
+@liblist = split ' ', $Config::Config{"DB_File_loadlibs"}
+ if defined $Config::Config{"DB_File_loadlibs"};
+
+bootstrap DB_File @liblist;
+
+# Preloaded methods go here. Autoload methods go after __END__, and are
+# processed by the autosplit program.
+
+1;
+__END__
+
+=cut
=head1 NAME
@@ -28,16 +271,15 @@ DB_File - Perl5 access to Berkeley DB
=head1 DESCRIPTION
-B<DB_File> is a module which allows Perl programs to make use of
-the facilities provided by Berkeley DB. If you intend to use this
-module you should really have a copy of the Berkeley DB manual
-page at hand. The interface defined here
-mirrors the Berkeley DB interface closely.
+B<DB_File> is a module which allows Perl programs to make use of the
+facilities provided by Berkeley DB. If you intend to use this
+module you should really have a copy of the Berkeley DB manualpage at
+hand. The interface defined here mirrors the Berkeley DB interface
+closely.
-Berkeley DB is a C library which provides a consistent interface to a number of
-database formats.
-B<DB_File> provides an interface to all three of the database types currently
-supported by Berkeley DB.
+Berkeley DB is a C library which provides a consistent interface to a
+number of database formats. B<DB_File> provides an interface to all
+three of the database types currently supported by Berkeley DB.
The file types are:
@@ -45,50 +287,50 @@ The file types are:
=item DB_HASH
-This database type allows arbitrary key/data pairs to be stored in data files.
-This is equivalent to the functionality provided by
-other hashing packages like DBM, NDBM, ODBM, GDBM, and SDBM.
-Remember though, the files created using DB_HASH are
-not compatible with any of the other packages mentioned.
+This database type allows arbitrary key/data pairs to be stored in data
+files. This is equivalent to the functionality provided by other
+hashing packages like DBM, NDBM, ODBM, GDBM, and SDBM. Remember though,
+the files created using DB_HASH are not compatible with any of the
+other packages mentioned.
-A default hashing algorithm, which will be adequate for most applications,
-is built into Berkeley DB.
-If you do need to use your own hashing algorithm it is possible to write your
-own in Perl and have B<DB_File> use it instead.
+A default hashing algorithm, which will be adequate for most
+applications, is built into Berkeley DB. If you do need to use your own
+hashing algorithm it is possible to write your own in Perl and have
+B<DB_File> use it instead.
=item DB_BTREE
-The btree format allows arbitrary key/data pairs to be stored in a sorted,
-balanced binary tree.
+The btree format allows arbitrary key/data pairs to be stored in a
+sorted, balanced binary tree.
-As with the DB_HASH format, it is possible to provide a user defined Perl routine
-to perform the comparison of keys. By default, though, the keys are stored
-in lexical order.
+As with the DB_HASH format, it is possible to provide a user defined
+Perl routine to perform the comparison of keys. By default, though, the
+keys are stored in lexical order.
=item DB_RECNO
-DB_RECNO allows both fixed-length and variable-length flat text files to be
-manipulated using
-the same key/value pair interface as in DB_HASH and DB_BTREE.
-In this case the key will consist of a record (line) number.
+DB_RECNO allows both fixed-length and variable-length flat text files
+to be manipulated using the same key/value pair interface as in DB_HASH
+and DB_BTREE. In this case the key will consist of a record (line)
+number.
=back
=head2 How does DB_File interface to Berkeley DB?
B<DB_File> allows access to Berkeley DB files using the tie() mechanism
-in Perl 5 (for full details, see L<perlfunc/tie()>).
-This facility allows B<DB_File> to access Berkeley DB files using
-either an associative array (for DB_HASH & DB_BTREE file types) or an
-ordinary array (for the DB_RECNO file type).
+in Perl 5 (for full details, see L<perlfunc/tie()>). This facility
+allows B<DB_File> to access Berkeley DB files using either an
+associative array (for DB_HASH & DB_BTREE file types) or an ordinary
+array (for the DB_RECNO file type).
-In addition to the tie() interface, it is also possible to use most of the
-functions provided in the Berkeley DB API.
+In addition to the tie() interface, it is also possible to use most of
+the functions provided in the Berkeley DB API.
=head2 Differences with Berkeley DB
-Berkeley DB uses the function dbopen() to open or create a
-database. Below is the C prototype for dbopen().
+Berkeley DB uses the function dbopen() to open or create a database.
+Below is the C prototype for dbopen().
DB*
dbopen (const char * file, int flags, int mode,
@@ -100,25 +342,24 @@ Depending on which of these is actually chosen, the final parameter,
I<openinfo> points to a data structure which allows tailoring of the
specific interface method.
-This interface is handled
-slightly differently in B<DB_File>. Here is an equivalent call using
-B<DB_File>.
+This interface is handled slightly differently in B<DB_File>. Here is
+an equivalent call using B<DB_File>.
tie %array, DB_File, $filename, $flags, $mode, $DB_HASH ;
-The C<filename>, C<flags> and C<mode> parameters are the direct equivalent
-of their dbopen() counterparts. The final parameter $DB_HASH
-performs the function of both the C<type> and C<openinfo>
-parameters in dbopen().
+The C<filename>, C<flags> and C<mode> parameters are the direct
+equivalent of their dbopen() counterparts. The final parameter $DB_HASH
+performs the function of both the C<type> and C<openinfo> parameters in
+dbopen().
-In the example above $DB_HASH is actually a reference to a hash object.
-B<DB_File> has three of these pre-defined references.
-Apart from $DB_HASH, there is also $DB_BTREE and $DB_RECNO.
+In the example above $DB_HASH is actually a reference to a hash
+object. B<DB_File> has three of these pre-defined references. Apart
+from $DB_HASH, there is also $DB_BTREE and $DB_RECNO.
-The keys allowed in each of these pre-defined references is limited to the names
-used in the equivalent C structure.
-So, for example, the $DB_HASH reference will only allow keys called C<bsize>,
-C<cachesize>, C<ffactor>, C<hash>, C<lorder> and C<nelem>.
+The keys allowed in each of these pre-defined references is limited to
+the names used in the equivalent C structure. So, for example, the
+$DB_HASH reference will only allow keys called C<bsize>, C<cachesize>,
+C<ffactor>, C<hash>, C<lorder> and C<nelem>.
To change one of these elements, just assign to it like this
@@ -134,33 +375,33 @@ RECNO arrays begins at 0 rather than 1 as in Berkeley DB.
=head2 In Memory Databases
-Berkeley DB allows the creation of in-memory databases by using NULL (that is, a
-C<(char *)0 in C) in
-place of the filename.
-B<DB_File> uses C<undef> instead of NULL to provide this functionality.
+Berkeley DB allows the creation of in-memory databases by using NULL
+(that is, a C<(char *)0 in C) in place of the filename. B<DB_File>
+uses C<undef> instead of NULL to provide this functionality.
=head2 Using the Berkeley DB Interface Directly
As well as accessing Berkeley DB using a tied hash or array, it is also
-possible to make direct use of most of the functions defined in the Berkeley DB
-documentation.
+possible to make direct use of most of the functions defined in the
+Berkeley DB documentation.
To do this you need to remember the return value from the tie.
$db = tie %hash, DB_File, "filename"
-Once you have done that, you can access the Berkeley DB API functions directly.
+Once you have done that, you can access the Berkeley DB API functions
+directly.
$db->put($key, $value, R_NOOVERWRITE) ;
-All the functions defined in L<dbx(3X)> are available except
-for close() and dbopen() itself.
-The B<DB_File> interface to these functions have been implemented to mirror
-the the way Berkeley DB works. In particular note that all the functions return
-only a status value. Whenever a Berkeley DB function returns data via one of
-its parameters, the B<DB_File> equivalent does exactly the same.
+All the functions defined in L<dbx(3X)> are available except for
+close() and dbopen() itself. The B<DB_File> interface to these
+functions have been implemented to mirror the the way Berkeley DB
+works. In particular note that all the functions return only a status
+value. Whenever a Berkeley DB function returns data via one of its
+parameters, the B<DB_File> equivalent does exactly the same.
All the constants defined in L<dbopen> are also available.
@@ -170,17 +411,16 @@ Below is a list of the functions available.
=item get
-Same as in C<recno> except that the flags parameter is optional.
-Remember the value
-associated with the key you request is returned in the $value parameter.
+Same as in C<recno> except that the flags parameter is optional.
+Remember the value associated with the key you request is returned in
+the $value parameter.
=item put
As usual the flags parameter is optional.
-If you use either the R_IAFTER or
-R_IBEFORE flags, the key parameter will have the record number of the inserted
-key/value pair set.
+If you use either the R_IAFTER or R_IBEFORE flags, the key parameter
+will have the record number of the inserted key/value pair set.
=item del
@@ -204,15 +444,15 @@ The flags parameter is optional.
=head1 EXAMPLES
-It is always a lot easier to understand something when you see a real example.
-So here are a few.
+It is always a lot easier to understand something when you see a real
+example. So here are a few.
=head2 Using HASH
use DB_File ;
use Fcntl ;
- tie %h, DB_File, "hashed", O_RDWR|O_CREAT, 0640, $DB_HASH ;
+ tie %h, "DB_File", "hashed", O_RDWR|O_CREAT, 0640, $DB_HASH ;
# Add a key/value pair to the file
$h{"apple"} = "orange" ;
@@ -227,9 +467,10 @@ So here are a few.
=head2 Using BTREE
-Here is sample of code which used BTREE. Just to make life more interesting
-the default comparision function will not be used. Instead a Perl sub, C<Compare()>,
-will be used to do a case insensitive comparison.
+Here is sample of code which used BTREE. Just to make life more
+interesting the default comparision function will not be used. Instead
+a Perl sub, C<Compare()>, will be used to do a case insensitive
+comparison.
use DB_File ;
use Fcntl ;
@@ -243,7 +484,7 @@ will be used to do a case insensitive comparison.
$DB_BTREE->{compare} = 'Compare' ;
- tie %h, DB_File, "tree", O_RDWR|O_CREAT, 0640, $DB_BTREE ;
+ tie %h, 'DB_File', "tree", O_RDWR|O_CREAT, 0640, $DB_BTREE ;
# Add a key/value pair to the file
$h{'Wall'} = 'Larry' ;
@@ -301,23 +542,37 @@ process if I<dbopen> returned an error. This allows file protection
errors to be caught at run time. Thanks to Judith Grass
<grass@cybercash.com> for spotting the bug.
+=head2 0.3
+
+Added prototype support for multiple btree compare callbacks.
+
+=head 1.0
+
+B<DB_File> has been in use for over a year. To reflect that, the
+version number has been incremented to 1.0.
+
+Added complete support for multiple concurrent callbacks.
+
+Using the I<push> method on an empty list didn't work properly. This
+has been fixed.
+
=head1 WARNINGS
-If you happen find any other functions defined in the source for this module
-that have not been mentioned in this document -- beware.
-I may drop them at a moments notice.
+If you happen find any other functions defined in the source for this
+module that have not been mentioned in this document -- beware. I may
+drop them at a moments notice.
-If you cannot find any, then either you didn't look very hard or the moment has
-passed and I have dropped them.
+If you cannot find any, then either you didn't look very hard or the
+moment has passed and I have dropped them.
=head1 BUGS
-Some older versions of Berkeley DB had problems with fixed length records
-using the RECNO file format. The newest version at the time of writing
-was 1.85 - this seems to have fixed the problems with RECNO.
+Some older versions of Berkeley DB had problems with fixed length
+records using the RECNO file format. The newest version at the time of
+writing was 1.85 - this seems to have fixed the problems with RECNO.
-I am sure there are bugs in the code. If you do find any, or can suggest any
-enhancements, I would welcome your comments.
+I am sure there are bugs in the code. If you do find any, or can
+suggest any enhancements, I would welcome your comments.
=head1 AVAILABILITY
@@ -328,252 +583,14 @@ directory C</ucb/4bsd/db.tar.gz>. It is I<not> under the GPL.
L<perl(1)>, L<dbopen(3)>, L<hash(3)>, L<recno(3)>, L<btree(3)>
-Berkeley DB is available from F<ftp.cs.berkeley.edu> in the directory F</ucb/4bsd>.
+Berkeley DB is available from F<ftp.cs.berkeley.edu> in the directory
+F</ucb/4bsd>.
=head1 AUTHOR
-The DB_File interface was written by
-Paul Marquess <pmarquess@bfsec.bt.co.uk>.
-Questions about the DB system itself may be addressed to
-Keith Bostic <bostic@cs.berkeley.edu>.
+The DB_File interface was written by Paul Marquess
+<pmarquess@bfsec.bt.co.uk>.
+Questions about the DB system itself may be addressed to Keith Bostic
+<bostic@cs.berkeley.edu>.
=cut
-
-package DB_File::HASHINFO ;
-use Carp;
-
-sub TIEHASH
-{
- bless {} ;
-}
-
-%elements = ( 'bsize' => 0,
- 'ffactor' => 0,
- 'nelem' => 0,
- 'cachesize' => 0,
- 'hash' => 0,
- 'lorder' => 0
- ) ;
-
-sub FETCH
-{
- return $_[0]{$_[1]} if defined $elements{$_[1]} ;
-
- croak "DB_File::HASHINFO::FETCH - Unknown element '$_[1]'" ;
-}
-
-
-sub STORE
-{
- if ( defined $elements{$_[1]} )
- {
- $_[0]{$_[1]} = $_[2] ;
- return ;
- }
-
- croak "DB_File::HASHINFO::STORE - Unknown element '$_[1]'" ;
-}
-
-sub DELETE
-{
- if ( defined $elements{$_[1]} )
- {
- delete ${$_[0]}{$_[1]} ;
- return ;
- }
-
- croak "DB_File::HASHINFO::DELETE - Unknown element '$_[1]'" ;
-}
-
-
-sub DESTROY {undef %{$_[0]} }
-sub FIRSTKEY { croak "DB_File::HASHINFO::FIRSTKEY is not implemented" }
-sub NEXTKEY { croak "DB_File::HASHINFO::NEXTKEY is not implemented" }
-sub EXISTS { croak "DB_File::HASHINFO::EXISTS is not implemented" }
-sub CLEAR { croak "DB_File::HASHINFO::CLEAR is not implemented" }
-
-package DB_File::BTREEINFO ;
-use Carp;
-
-sub TIEHASH
-{
- bless {} ;
-}
-
-%elements = ( 'flags' => 0,
- 'cachesize' => 0,
- 'maxkeypage' => 0,
- 'minkeypage' => 0,
- 'psize' => 0,
- 'compare' => 0,
- 'prefix' => 0,
- 'lorder' => 0
- ) ;
-
-sub FETCH
-{
- return $_[0]{$_[1]} if defined $elements{$_[1]} ;
-
- croak "DB_File::BTREEINFO::FETCH - Unknown element '$_[1]'" ;
-}
-
-
-sub STORE
-{
- if ( defined $elements{$_[1]} )
- {
- $_[0]{$_[1]} = $_[2] ;
- return ;
- }
-
- croak "DB_File::BTREEINFO::STORE - Unknown element '$_[1]'" ;
-}
-
-sub DELETE
-{
- if ( defined $elements{$_[1]} )
- {
- delete ${$_[0]}{$_[1]} ;
- return ;
- }
-
- croak "DB_File::BTREEINFO::DELETE - Unknown element '$_[1]'" ;
-}
-
-
-sub DESTROY {undef %{$_[0]} }
-sub FIRSTKEY { croak "DB_File::BTREEINFO::FIRSTKEY is not implemented" }
-sub NEXTKEY { croak "DB_File::BTREEINFO::NEXTKEY is not implemented" }
-sub EXISTS { croak "DB_File::BTREEINFO::EXISTS is not implemented" }
-sub CLEAR { croak "DB_File::BTREEINFO::CLEAR is not implemented" }
-
-package DB_File::RECNOINFO ;
-use Carp;
-
-sub TIEHASH
-{
- bless {} ;
-}
-
-%elements = ( 'bval' => 0,
- 'cachesize' => 0,
- 'psize' => 0,
- 'flags' => 0,
- 'lorder' => 0,
- 'reclen' => 0,
- 'bfname' => 0
- ) ;
-sub FETCH
-{
- return $_[0]{$_[1]} if defined $elements{$_[1]} ;
-
- croak "DB_File::RECNOINFO::FETCH - Unknown element '$_[1]'" ;
-}
-
-
-sub STORE
-{
- if ( defined $elements{$_[1]} )
- {
- $_[0]{$_[1]} = $_[2] ;
- return ;
- }
-
- croak "DB_File::RECNOINFO::STORE - Unknown element '$_[1]'" ;
-}
-
-sub DELETE
-{
- if ( defined $elements{$_[1]} )
- {
- delete ${$_[0]}{$_[1]} ;
- return ;
- }
-
- croak "DB_File::RECNOINFO::DELETE - Unknown element '$_[1]'" ;
-}
-
-
-sub DESTROY {undef %{$_[0]} }
-sub FIRSTKEY { croak "DB_File::RECNOINFO::FIRSTKEY is not implemented" }
-sub NEXTKEY { croak "DB_File::RECNOINFO::NEXTKEY is not implemented" }
-sub EXISTS { croak "DB_File::BTREEINFO::EXISTS is not implemented" }
-sub CLEAR { croak "DB_File::BTREEINFO::CLEAR is not implemented" }
-
-
-
-package DB_File ;
-use Carp;
-
-#typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
-$DB_BTREE = TIEHASH DB_File::BTREEINFO ;
-$DB_HASH = TIEHASH DB_File::HASHINFO ;
-$DB_RECNO = TIEHASH DB_File::RECNOINFO ;
-
-require TieHash;
-require Exporter;
-use AutoLoader;
-require DynaLoader;
-@ISA = qw(TieHash Exporter DynaLoader);
-@EXPORT = qw(
- $DB_BTREE $DB_HASH $DB_RECNO
- BTREEMAGIC
- BTREEVERSION
- DB_LOCK
- DB_SHMEM
- DB_TXN
- HASHMAGIC
- HASHVERSION
- MAX_PAGE_NUMBER
- MAX_PAGE_OFFSET
- MAX_REC_NUMBER
- RET_ERROR
- RET_SPECIAL
- RET_SUCCESS
- R_CURSOR
- R_DUP
- R_FIRST
- R_FIXEDLEN
- R_IAFTER
- R_IBEFORE
- R_LAST
- R_NEXT
- R_NOKEY
- R_NOOVERWRITE
- R_PREV
- R_RECNOSYNC
- R_SETCURSOR
- R_SNAPSHOT
- __R_UNUSED
-);
-
-sub AUTOLOAD {
- local($constname);
- ($constname = $AUTOLOAD) =~ s/.*:://;
- $val = constant($constname, @_ ? $_[0] : 0);
- if ($! != 0) {
- if ($! =~ /Invalid/) {
- $AutoLoader::AUTOLOAD = $AUTOLOAD;
- goto &AutoLoader::AUTOLOAD;
- }
- else {
- ($pack,$file,$line) = caller;
- croak "Your vendor has not defined DB macro $constname, used at $file line $line.
-";
- }
- }
- eval "sub $AUTOLOAD { $val }";
- goto &$AUTOLOAD;
-}
-
-@liblist = ();
-@liblist = split ' ', $Config::Config{"DB_File_loadlibs"}
- if defined $Config::Config{"DB_File_loadlibs"};
-
-bootstrap DB_File @liblist;
-
-# Preloaded methods go here. Autoload methods go after __END__, and are
-# processed by the autosplit program.
-
-1;
-__END__
diff --git a/ext/DB_File/DB_File.xs b/ext/DB_File/DB_File.xs
index 0541668e24..8abb230da1 100644
--- a/ext/DB_File/DB_File.xs
+++ b/ext/DB_File/DB_File.xs
@@ -3,14 +3,17 @@
DB_File.xs -- Perl 5 interface to Berkeley DB
written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
- last modified 19th May 1995
- version 0.2
+ last modified 7th October 1995
+ version 1.0
All comments/suggestions/problems are welcome
Changes:
0.1 - Initial Release
0.2 - No longer bombs out if dbopen returns an error.
+ 0.3 - Added some support for multiple btree compares
+ 1.0 - Complete support for multiple callbacks added.
+ Fixed a problem with pushing a value onto an empty list.
*/
#include "EXTERN.h"
@@ -21,7 +24,15 @@
#include <fcntl.h>
-typedef DB * DB_File;
+typedef struct {
+ DBTYPE type ;
+ DB * dbp ;
+ SV * compare ;
+ SV * prefix ;
+ SV * hash ;
+ } DB_File_type;
+
+typedef DB_File_type * DB_File ;
typedef DBT DBTKEY ;
union INFO {
@@ -30,25 +41,21 @@ union INFO {
BTREEINFO btree ;
} ;
-typedef struct {
- SV * sub ;
- } CallBackInfo ;
-
/* #define TRACE */
-#define db_DESTROY(db) (db->close)(db)
-#define db_DELETE(db, key, flags) (db->del)(db, &key, flags)
-#define db_STORE(db, key, value, flags) (db->put)(db, &key, &value, flags)
-#define db_FETCH(db, key, flags) (db->get)(db, &key, &value, flags)
+#define db_DESTROY(db) (db->dbp->close)(db->dbp)
+#define db_DELETE(db, key, flags) (db->dbp->del)(db->dbp, &key, flags)
+#define db_STORE(db, key, value, flags) (db->dbp->put)(db->dbp, &key, &value, flags)
+#define db_FETCH(db, key, flags) (db->dbp->get)(db->dbp, &key, &value, flags)
-#define db_close(db) (db->close)(db)
-#define db_del(db, key, flags) (db->del)(db, &key, flags)
-#define db_fd(db) (db->fd)(db)
-#define db_put(db, key, value, flags) (db->put)(db, &key, &value, flags)
-#define db_get(db, key, value, flags) (db->get)(db, &key, &value, flags)
-#define db_seq(db, key, value, flags) (db->seq)(db, &key, &value, flags)
-#define db_sync(db, flags) (db->sync)(db, flags)
+#define db_close(db) (db->dbp->close)(db->dbp)
+#define db_del(db, key, flags) (db->dbp->del)(db->dbp, &key, flags)
+#define db_fd(db) (db->dbp->fd)(db->dbp)
+#define db_put(db, key, value, flags) (db->dbp->put)(db->dbp, &key, &value, flags)
+#define db_get(db, key, value, flags) (db->dbp->get)(db->dbp, &key, &value, flags)
+#define db_seq(db, key, value, flags) (db->dbp->seq)(db->dbp, &key, &value, flags)
+#define db_sync(db, flags) (db->dbp->sync)(db->dbp, flags)
#define OutputValue(arg, name) \
@@ -57,7 +64,7 @@ typedef struct {
#define OutputKey(arg, name) \
{ if (RETVAL == 0) \
{ \
- if (db->close != DB_recno_close) \
+ if (db->type != DB_RECNO) \
sv_setpvn(arg, name.data, name.size); \
else \
sv_setiv(arg, (I32)*(I32*)name.data - 1); \
@@ -65,13 +72,10 @@ typedef struct {
}
/* Internal Global Data */
-
-static recno_t Value ;
-static int (*DB_recno_close)() = NULL ;
-
-static CallBackInfo hash_callback = { 0 } ;
-static CallBackInfo compare_callback = { 0 } ;
-static CallBackInfo prefix_callback = { 0 } ;
+static recno_t Value ;
+static DB_File CurrentDB ;
+static recno_t zero = 0 ;
+static DBTKEY empty = { &zero, sizeof(recno_t) } ;
static int
@@ -105,7 +109,7 @@ const DBT * key2 ;
PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
PUTBACK ;
- count = perl_call_sv(compare_callback.sub, G_SCALAR);
+ count = perl_call_sv(CurrentDB->compare, G_SCALAR);
SPAGAIN ;
@@ -152,7 +156,7 @@ const DBT * key2 ;
PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
PUTBACK ;
- count = perl_call_sv(prefix_callback.sub, G_SCALAR);
+ count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
SPAGAIN ;
@@ -184,7 +188,7 @@ size_t size ;
XPUSHs(sv_2mortal(newSVpv((char*)data,size)));
PUTBACK ;
- count = perl_call_sv(hash_callback.sub, G_SCALAR);
+ count = perl_call_sv(CurrentDB->hash, G_SCALAR);
SPAGAIN ;
@@ -256,7 +260,7 @@ BTREEINFO btree ;
static I32
GetArrayLength(db)
-DB_File db ;
+DB * db ;
{
DBT key ;
DBT value ;
@@ -282,10 +286,12 @@ char * string ;
SV ** svp;
HV * action ;
union INFO info ;
- DB_File RETVAL ;
+ DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ;
void * openinfo = NULL ;
- DBTYPE type = DB_HASH ;
+ /* DBTYPE type = DB_HASH ; */
+ RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
+ RETVAL->type = DB_HASH ;
if (sv)
{
@@ -295,7 +301,7 @@ char * string ;
action = (HV*)SvRV(sv);
if (sv_isa(sv, "DB_File::HASHINFO"))
{
- type = DB_HASH ;
+ RETVAL->type = DB_HASH ;
openinfo = (void*)&info ;
svp = hv_fetch(action, "hash", 4, FALSE);
@@ -303,7 +309,7 @@ char * string ;
if (svp && SvOK(*svp))
{
info.hash.hash = hash_cb ;
- hash_callback.sub = *svp ;
+ RETVAL->hash = newSVsv(*svp) ;
}
else
info.hash.hash = NULL ;
@@ -327,14 +333,14 @@ char * string ;
}
else if (sv_isa(sv, "DB_File::BTREEINFO"))
{
- type = DB_BTREE ;
+ RETVAL->type = DB_BTREE ;
openinfo = (void*)&info ;
svp = hv_fetch(action, "compare", 7, FALSE);
if (svp && SvOK(*svp))
{
info.btree.compare = btree_compare ;
- compare_callback.sub = *svp ;
+ RETVAL->compare = newSVsv(*svp) ;
}
else
info.btree.compare = NULL ;
@@ -343,7 +349,7 @@ char * string ;
if (svp && SvOK(*svp))
{
info.btree.prefix = btree_prefix ;
- prefix_callback.sub = *svp ;
+ RETVAL->prefix = newSVsv(*svp) ;
}
else
info.btree.prefix = NULL ;
@@ -371,7 +377,7 @@ char * string ;
}
else if (sv_isa(sv, "DB_File::RECNOINFO"))
{
- type = DB_RECNO ;
+ RETVAL->type = DB_RECNO ;
openinfo = (void *)&info ;
svp = hv_fetch(action, "flags", 5, FALSE);
@@ -415,14 +421,16 @@ char * string ;
}
- RETVAL = dbopen(name, flags, mode, type, openinfo) ;
+ RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ;
+#if 0
/* kludge mode on: RETVAL->type for DB_RECNO is set to DB_BTREE
so remember a DB_RECNO by saving the address
of one of it's internal routines
*/
- if (RETVAL && type == DB_RECNO)
- DB_recno_close = RETVAL->close ;
+ if (RETVAL->dbp && type == DB_RECNO)
+ DB_recno_close = RETVAL->dbp->close ;
+#endif
return (RETVAL) ;
@@ -710,6 +718,16 @@ BOOT:
int
db_DESTROY(db)
DB_File db
+ INIT:
+ CurrentDB = db ;
+ CLEANUP:
+ if (db->hash)
+ SvREFCNT_dec(db->hash) ;
+ if (db->compare)
+ SvREFCNT_dec(db->compare) ;
+ if (db->prefix)
+ SvREFCNT_dec(db->prefix) ;
+ Safefree(db) ;
int
@@ -717,6 +735,8 @@ db_DELETE(db, key, flags=0)
DB_File db
DBTKEY key
u_int flags
+ INIT:
+ CurrentDB = db ;
int
db_FETCH(db, key, flags=0)
@@ -727,7 +747,8 @@ db_FETCH(db, key, flags=0)
{
DBT value ;
- RETVAL = (db->get)(db, &key, &value, flags) ;
+ CurrentDB = db ;
+ RETVAL = (db->dbp->get)(db->dbp, &key, &value, flags) ;
ST(0) = sv_newmortal();
if (RETVAL == 0)
sv_setpvn(ST(0), value.data, value.size);
@@ -739,6 +760,8 @@ db_STORE(db, key, value, flags=0)
DBTKEY key
DBT value
u_int flags
+ INIT:
+ CurrentDB = db ;
int
@@ -749,11 +772,12 @@ db_FIRSTKEY(db)
DBTKEY key ;
DBT value ;
- RETVAL = (db->seq)(db, &key, &value, R_FIRST) ;
+ CurrentDB = db ;
+ RETVAL = (db->dbp->seq)(db->dbp, &key, &value, R_FIRST) ;
ST(0) = sv_newmortal();
if (RETVAL == 0)
{
- if (db->type != DB_RECNO)
+ if (db->dbp->type != DB_RECNO)
sv_setpvn(ST(0), key.data, key.size);
else
sv_setiv(ST(0), (I32)*(I32*)key.data - 1);
@@ -768,11 +792,12 @@ db_NEXTKEY(db, key)
{
DBT value ;
- RETVAL = (db->seq)(db, &key, &value, R_NEXT) ;
+ CurrentDB = db ;
+ RETVAL = (db->dbp->seq)(db->dbp, &key, &value, R_NEXT) ;
ST(0) = sv_newmortal();
if (RETVAL == 0)
{
- if (db->type != DB_RECNO)
+ if (db->dbp->type != DB_RECNO)
sv_setpvn(ST(0), key.data, key.size);
else
sv_setiv(ST(0), (I32)*(I32*)key.data - 1);
@@ -793,6 +818,7 @@ unshift(db, ...)
int i ;
int One ;
+ CurrentDB = db ;
RETVAL = -1 ;
for (i = items-1 ; i > 0 ; --i)
{
@@ -801,7 +827,7 @@ unshift(db, ...)
One = 1 ;
key.data = &One ;
key.size = sizeof(int) ;
- RETVAL = (db->put)(db, &key, &value, R_IBEFORE) ;
+ RETVAL = (db->dbp->put)(db->dbp, &key, &value, R_IBEFORE) ;
if (RETVAL != 0)
break;
}
@@ -817,13 +843,14 @@ pop(db)
DBTKEY key ;
DBT value ;
+ CurrentDB = db ;
/* First get the final value */
- RETVAL = (db->seq)(db, &key, &value, R_LAST) ;
+ RETVAL = (db->dbp->seq)(db->dbp, &key, &value, R_LAST) ;
ST(0) = sv_newmortal();
/* Now delete it */
if (RETVAL == 0)
{
- RETVAL = (db->del)(db, &key, R_CURSOR) ;
+ RETVAL = (db->dbp->del)(db->dbp, &key, R_CURSOR) ;
if (RETVAL == 0)
sv_setpvn(ST(0), value.data, value.size);
}
@@ -837,13 +864,14 @@ shift(db)
DBTKEY key ;
DBT value ;
+ CurrentDB = db ;
/* get the first value */
- RETVAL = (db->seq)(db, &key, &value, R_FIRST) ;
+ RETVAL = (db->dbp->seq)(db->dbp, &key, &value, R_FIRST) ;
ST(0) = sv_newmortal();
/* Now delete it */
if (RETVAL == 0)
{
- RETVAL = (db->del)(db, &key, R_CURSOR) ;
+ RETVAL = (db->dbp->del)(db->dbp, &key, R_CURSOR) ;
if (RETVAL == 0)
sv_setpvn(ST(0), value.data, value.size);
}
@@ -856,22 +884,25 @@ push(db, ...)
CODE:
{
DBTKEY key ;
+ DBTKEY * keyptr = &key ;
DBT value ;
int i ;
+ CurrentDB = db ;
/* Set the Cursor to the Last element */
- RETVAL = (db->seq)(db, &key, &value, R_LAST) ;
- if (RETVAL == 0)
+ RETVAL = (db->dbp->seq)(db->dbp, &key, &value, R_LAST) ;
+ if (RETVAL >= 0)
{
- /* for (i = 1 ; i < items ; ++i) */
- for (i = items - 1 ; i > 0 ; --i)
- {
- value.data = SvPV(ST(i), na) ;
- value.size = na ;
- RETVAL = (db->put)(db, &key, &value, R_IAFTER) ;
- if (RETVAL != 0)
- break;
- }
+ if (RETVAL == 1)
+ keyptr = &empty ;
+ for (i = items - 1 ; i > 0 ; --i)
+ {
+ value.data = SvPV(ST(i), na) ;
+ value.size = na ;
+ RETVAL = (db->dbp->put)(db->dbp, keyptr, &value, R_IAFTER) ;
+ if (RETVAL != 0)
+ break;
+ }
}
}
OUTPUT:
@@ -882,7 +913,8 @@ I32
length(db)
DB_File db
CODE:
- RETVAL = GetArrayLength(db) ;
+ CurrentDB = db ;
+ RETVAL = GetArrayLength(db->dbp) ;
OUTPUT:
RETVAL
@@ -896,6 +928,8 @@ db_del(db, key, flags=0)
DB_File db
DBTKEY key
u_int flags
+ INIT:
+ CurrentDB = db ;
int
@@ -904,6 +938,8 @@ db_get(db, key, value, flags=0)
DBTKEY key
DBT value
u_int flags
+ INIT:
+ CurrentDB = db ;
OUTPUT:
value
@@ -913,17 +949,23 @@ db_put(db, key, value, flags=0)
DBTKEY key
DBT value
u_int flags
+ INIT:
+ CurrentDB = db ;
OUTPUT:
key if (flags & (R_IAFTER|R_IBEFORE)) OutputKey(ST(1), key);
int
db_fd(db)
DB_File db
+ INIT:
+ CurrentDB = db ;
int
db_sync(db, flags=0)
DB_File db
u_int flags
+ INIT:
+ CurrentDB = db ;
int
@@ -932,6 +974,8 @@ db_seq(db, key, value, flags)
DBTKEY key
DBT value
u_int flags
+ INIT:
+ CurrentDB = db ;
OUTPUT:
key
value
diff --git a/ext/DB_File/Makefile.PL b/ext/DB_File/Makefile.PL
index c300d8569f..3ad8015d95 100644
--- a/ext/DB_File/Makefile.PL
+++ b/ext/DB_File/Makefile.PL
@@ -1,2 +1,9 @@
use ExtUtils::MakeMaker;
-WriteMakefile(LIBS => ["-L/usr/local/lib -ldb"]);
+
+WriteMakefile(
+ NAME => 'DB_File',
+ LIBS => ["-L/usr/local/lib -ldb"],
+ #INC => '-I/usr/local/include',
+ VERSION => 1.0,
+ );
+
diff --git a/ext/DB_File/typemap b/ext/DB_File/typemap
index 242fa041d2..4acc65e078 100644
--- a/ext/DB_File/typemap
+++ b/ext/DB_File/typemap
@@ -15,7 +15,7 @@ DBTKEY T_dbtkeydatum
INPUT
T_dbtkeydatum
- if (db->close != DB_recno_close)
+ if (db->type != DB_RECNO)
{
$var.data = SvPV($arg, na);
$var.size = (int)na;