3 DB_File.xs -- Perl 5 interface to Berkeley DB
5 written by Paul Marquess <Paul.Marquess@btinternet.com>
6 last modified 19th November 1998
9 All comments/suggestions/problems are welcome
11 Copyright (c) 1995, 1996, 1997, 1998 Paul Marquess. All rights reserved.
12 This program is free software; you can redistribute it and/or
13 modify it under the same terms as Perl itself.
17 0.2 - No longer bombs out if dbopen returns an error.
18 0.3 - Added some support for multiple btree compares
19 1.0 - Complete support for multiple callbacks added.
20 Fixed a problem with pushing a value onto an empty list.
21 1.01 - Fixed a SunOS core dump problem.
22 The return value from TIEHASH wasn't set to NULL when
23 dbopen returned an error.
24 1.02 - Use ALIAS to define TIEARRAY.
25 Removed some redundant commented code.
26 Merged OS2 code into the main distribution.
27 Allow negative subscripts with RECNO interface.
28 Changed the default flags to O_CREAT|O_RDWR
30 1.04 - fixed a couple of bugs in hash_cb. Patches supplied by
31 Dave Hammen, hammen@gothamcity.jsc.nasa.gov
32 1.05 - Added logic to allow prefix & hash types to be specified via
34 1.06 - Minor namespace cleanup: Localized PrintBtree.
35 1.07 - Fixed bug with RECNO, where bval wasn't defaulting to "\n".
36 1.08 - No change to DB_File.xs
37 1.09 - Default mode for dbopen changed to 0666
38 1.10 - Fixed fd method so that it still returns -1 for
39 in-memory files when db 1.86 is used.
40 1.11 - No change to DB_File.xs
41 1.12 - No change to DB_File.xs
42 1.13 - Tidied up a few casts.
43 1.14 - Made it illegal to tie an associative array to a RECNO
44 database and an ordinary array to a HASH or BTREE database.
45 1.50 - Make work with both DB 1.x or DB 2.x
46 1.51 - Fixed a bug in mapping 1.x O_RDONLY flag to 2.x DB_RDONLY equivalent
47 1.52 - Patch from Gisle Aas <gisle@aas.no> to suppress "use of
48 undefined value" warning with db_get and db_seq.
49 1.53 - Added DB_RENUMBER to flags for recno.
50 1.54 - Fixed bug in the fd method
51 1.55 - Fix for AIX from Jarkko Hietaniemi
52 1.56 - No change to DB_File.xs
53 1.57 - added the #undef op to allow building with Threads support.
54 1.58 - Fixed a problem with the use of sv_setpvn. When the
55 size is specified as 0, it does a strlen on the data.
56 This was ok for DB 1.x, but isn't for DB 2.x.
57 1.59 - No change to DB_File.xs
58 1.60 - Some code tidy up
59 1.61 - added flagSet macro for DB 2.5.x
60 fixed typo in O_RDONLY test.
61 1.62 - No change to DB_File.xs
62 1.63 - Fix to alllow DB 2.6.x to build.
74 #include "patchlevel.h"
75 #define PERL_VERSION PATCHLEVEL
78 /* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
79 * shortly #included by the <db.h>) __attribute__ to the possibly
80 * already defined __attribute__, for example by GNUC or by Perl. */
84 /* If Perl has been compiled with Threads support,the symbol op will
85 be defined here. This clashes with a field name in db.h, so get rid of it.
98 #ifdef DB_VERSION_MAJOR
100 /* map version 2 features & constants onto their version 1 equivalent */
105 #define DB_Prefix_t size_t
110 #define DB_Hash_t u_int32_t
112 /* DBTYPE stays the same */
113 /* HASHINFO, RECNOINFO and BTREEINFO map to DB_INFO */
114 typedef DB_INFO INFO ;
116 /* version 2 has db_recno_t in place of recno_t */
117 typedef db_recno_t recno_t;
120 #define R_CURSOR DB_SET_RANGE
121 #define R_FIRST DB_FIRST
122 #define R_IAFTER DB_AFTER
123 #define R_IBEFORE DB_BEFORE
124 #define R_LAST DB_LAST
125 #define R_NEXT DB_NEXT
126 #define R_NOOVERWRITE DB_NOOVERWRITE
127 #define R_PREV DB_PREV
128 #define R_SETCURSOR 0
129 #define R_RECNOSYNC 0
130 #define R_FIXEDLEN DB_FIXEDLEN
133 #define db_HA_hash h_hash
134 #define db_HA_ffactor h_ffactor
135 #define db_HA_nelem h_nelem
136 #define db_HA_bsize db_pagesize
137 #define db_HA_cachesize db_cachesize
138 #define db_HA_lorder db_lorder
140 #define db_BT_compare bt_compare
141 #define db_BT_prefix bt_prefix
142 #define db_BT_flags flags
143 #define db_BT_psize db_pagesize
144 #define db_BT_cachesize db_cachesize
145 #define db_BT_lorder db_lorder
146 #define db_BT_maxkeypage
147 #define db_BT_minkeypage
150 #define db_RE_reclen re_len
151 #define db_RE_flags flags
152 #define db_RE_bval re_pad
153 #define db_RE_bfname re_source
154 #define db_RE_psize db_pagesize
155 #define db_RE_cachesize db_cachesize
156 #define db_RE_lorder db_lorder
160 #define do_SEQ(db, key, value, flag) (db->cursor->c_get)(db->cursor, &key, &value, flag)
163 #define DBT_flags(x) x.flags = 0
164 #define DB_flags(x, v) x |= v
166 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
167 #define flagSet(flags, bitmask) ((flags) & (bitmask))
169 #define flagSet(flags, bitmask) (((flags) & DB_OPFLAGS_MASK) == (bitmask))
172 #else /* db version 1.x */
185 #define DB_Prefix_t mDB_Prefix_t
192 #define DB_Hash_t mDB_Hash_t
195 #define db_HA_hash hash.hash
196 #define db_HA_ffactor hash.ffactor
197 #define db_HA_nelem hash.nelem
198 #define db_HA_bsize hash.bsize
199 #define db_HA_cachesize hash.cachesize
200 #define db_HA_lorder hash.lorder
202 #define db_BT_compare btree.compare
203 #define db_BT_prefix btree.prefix
204 #define db_BT_flags btree.flags
205 #define db_BT_psize btree.psize
206 #define db_BT_cachesize btree.cachesize
207 #define db_BT_lorder btree.lorder
208 #define db_BT_maxkeypage btree.maxkeypage
209 #define db_BT_minkeypage btree.minkeypage
211 #define db_RE_reclen recno.reclen
212 #define db_RE_flags recno.flags
213 #define db_RE_bval recno.bval
214 #define db_RE_bfname recno.bfname
215 #define db_RE_psize recno.psize
216 #define db_RE_cachesize recno.cachesize
217 #define db_RE_lorder recno.lorder
221 #define do_SEQ(db, key, value, flag) (db->dbp->seq)(db->dbp, &key, &value, flag)
223 #define DB_flags(x, v)
224 #define flagSet(flags, bitmask) ((flags) & (bitmask))
226 #endif /* db version 1 */
230 #define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, TXN &key, flags)
231 #define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, flags)
232 #define db_FETCH(db, key, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
234 #define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags)
235 #define db_get(db, key, value, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
237 #ifdef DB_VERSION_MAJOR
238 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp, 0)
239 #define db_close(db) ((db->dbp)->close)(db->dbp, 0)
240 #define db_del(db, key, flags) (flagSet(flags, R_CURSOR) \
241 ? ((db->cursor)->c_del)(db->cursor, 0) \
242 : ((db->dbp)->del)(db->dbp, NULL, &key, flags) )
246 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp)
247 #define db_close(db) ((db->dbp)->close)(db->dbp)
248 #define db_del(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags)
249 #define db_put(db, key, value, flags) ((db->dbp)->put)(db->dbp, &key, &value, flags)
254 #define db_seq(db, key, value, flags) do_SEQ(db, key, value, flags)
264 #ifdef DB_VERSION_MAJOR
269 typedef DB_File_type * DB_File ;
272 #define my_sv_setpvn(sv, d, s) sv_setpvn(sv, (s ? d : (void*)""), s)
274 #define OutputValue(arg, name) \
275 { if (RETVAL == 0) { \
276 my_sv_setpvn(arg, name.data, name.size) ; \
280 #define OutputKey(arg, name) \
283 if (db->type != DB_RECNO) { \
284 my_sv_setpvn(arg, name.data, name.size); \
287 sv_setiv(arg, (I32)*(I32*)name.data - 1); \
292 /* Internal Global Data */
293 static recno_t Value ;
294 static recno_t zero = 0 ;
295 static DB_File CurrentDB ;
296 static DBTKEY empty ;
298 #ifdef DB_VERSION_MAJOR
301 db_put(db, key, value, flags)
310 if (flagSet(flags, R_CURSOR)) {
311 status = ((db->cursor)->c_del)(db->cursor, 0);
315 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
318 flags &= ~DB_OPFLAGS_MASK ;
323 return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;
327 #endif /* DB_VERSION_MAJOR */
332 SV * ver_sv = perl_get_sv("DB_File::db_version", TRUE) ;
333 #ifdef DB_VERSION_MAJOR
334 int Major, Minor, Patch ;
336 (void)db_version(&Major, &Minor, &Patch) ;
338 /* check that libdb is recent enough */
339 if (Major == 2 && Minor == 0 && Patch < 5)
340 croak("DB_File needs Berkeley DB 2.0.5 or greater, you have %d.%d.%d\n",
341 Major, Minor, Patch) ;
344 sv_setpvf(ver_sv, "%d.%d", Major, Minor) ;
348 sprintf(buffer, "%d.%d", Major, Minor) ;
349 sv_setpv(ver_sv, buffer) ;
354 sv_setiv(ver_sv, 1) ;
361 btree_compare(key1, key2)
366 void * data1, * data2 ;
373 /* As newSVpv will assume that the data pointer is a null terminated C
374 string if the size parameter is 0, make sure that data points to an
375 empty string if the length is 0
387 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
388 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
391 count = perl_call_sv(CurrentDB->compare, G_SCALAR);
396 croak ("DB_File btree_compare: expected 1 return value from compare sub, got %d\n", count) ;
408 btree_prefix(key1, key2)
413 void * data1, * data2 ;
420 /* As newSVpv will assume that the data pointer is a null terminated C
421 string if the size parameter is 0, make sure that data points to an
422 empty string if the length is 0
434 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
435 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
438 count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
443 croak ("DB_File btree_prefix: expected 1 return value from prefix sub, got %d\n", count) ;
466 /* DGH - Next two lines added to fix corrupted stack problem */
472 XPUSHs(sv_2mortal(newSVpv((char*)data,size)));
475 count = perl_call_sv(CurrentDB->hash, G_SCALAR);
480 croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ;
498 printf ("HASH Info\n") ;
499 printf (" hash = %s\n",
500 (hash->db_HA_hash != NULL ? "redefined" : "default")) ;
501 printf (" bsize = %d\n", hash->db_HA_bsize) ;
502 printf (" ffactor = %d\n", hash->db_HA_ffactor) ;
503 printf (" nelem = %d\n", hash->db_HA_nelem) ;
504 printf (" cachesize = %d\n", hash->db_HA_cachesize) ;
505 printf (" lorder = %d\n", hash->db_HA_lorder) ;
513 printf ("RECNO Info\n") ;
514 printf (" flags = %d\n", recno->db_RE_flags) ;
515 printf (" cachesize = %d\n", recno->db_RE_cachesize) ;
516 printf (" psize = %d\n", recno->db_RE_psize) ;
517 printf (" lorder = %d\n", recno->db_RE_lorder) ;
518 printf (" reclen = %ul\n", (unsigned long)recno->db_RE_reclen) ;
519 printf (" bval = %d 0x%x\n", recno->db_RE_bval, recno->db_RE_bval) ;
520 printf (" bfname = %d [%s]\n", recno->db_RE_bfname, recno->db_RE_bfname) ;
527 printf ("BTREE Info\n") ;
528 printf (" compare = %s\n",
529 (btree->db_BT_compare ? "redefined" : "default")) ;
530 printf (" prefix = %s\n",
531 (btree->db_BT_prefix ? "redefined" : "default")) ;
532 printf (" flags = %d\n", btree->db_BT_flags) ;
533 printf (" cachesize = %d\n", btree->db_BT_cachesize) ;
534 printf (" psize = %d\n", btree->db_BT_psize) ;
535 #ifndef DB_VERSION_MAJOR
536 printf (" maxkeypage = %d\n", btree->db_BT_maxkeypage) ;
537 printf (" minkeypage = %d\n", btree->db_BT_minkeypage) ;
539 printf (" lorder = %d\n", btree->db_BT_lorder) ;
544 #define PrintRecno(recno)
545 #define PrintHash(hash)
546 #define PrintBtree(btree)
561 RETVAL = do_SEQ(db, key, value, R_LAST) ;
563 RETVAL = *(I32 *)key.data ;
564 else /* No key means empty file */
567 return ((I32)RETVAL) ;
571 GetRecnoKey(db, value)
576 /* Get the length of the array */
577 I32 length = GetArrayLength(db) ;
579 /* check for attempt to write before start of array */
580 if (length + value + 1 <= 0)
581 croak("Modification of non-creatable array value attempted, subscript %ld", (long)value) ;
583 value = length + value + 1 ;
592 ParseOpenInfo(isHASH, name, flags, mode, sv)
601 DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ;
602 void * openinfo = NULL ;
603 INFO * info = &RETVAL->info ;
606 /* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
607 Zero(RETVAL, 1, DB_File_type) ;
609 /* Default to HASH */
610 RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
611 RETVAL->type = DB_HASH ;
613 /* DGH - Next line added to avoid SEGV on existing hash DB */
616 /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */
617 RETVAL->in_memory = (name == NULL) ;
622 croak ("type parameter is not a reference") ;
624 svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ;
625 if (svp && SvOK(*svp))
626 action = (HV*) SvRV(*svp) ;
628 croak("internal error") ;
630 if (sv_isa(sv, "DB_File::HASHINFO"))
634 croak("DB_File can only tie an associative array to a DB_HASH database") ;
636 RETVAL->type = DB_HASH ;
637 openinfo = (void*)info ;
639 svp = hv_fetch(action, "hash", 4, FALSE);
641 if (svp && SvOK(*svp))
643 info->db_HA_hash = hash_cb ;
644 RETVAL->hash = newSVsv(*svp) ;
647 info->db_HA_hash = NULL ;
649 svp = hv_fetch(action, "ffactor", 7, FALSE);
650 info->db_HA_ffactor = svp ? SvIV(*svp) : 0;
652 svp = hv_fetch(action, "nelem", 5, FALSE);
653 info->db_HA_nelem = svp ? SvIV(*svp) : 0;
655 svp = hv_fetch(action, "bsize", 5, FALSE);
656 info->db_HA_bsize = svp ? SvIV(*svp) : 0;
658 svp = hv_fetch(action, "cachesize", 9, FALSE);
659 info->db_HA_cachesize = svp ? SvIV(*svp) : 0;
661 svp = hv_fetch(action, "lorder", 6, FALSE);
662 info->db_HA_lorder = svp ? SvIV(*svp) : 0;
666 else if (sv_isa(sv, "DB_File::BTREEINFO"))
669 croak("DB_File can only tie an associative array to a DB_BTREE database");
671 RETVAL->type = DB_BTREE ;
672 openinfo = (void*)info ;
674 svp = hv_fetch(action, "compare", 7, FALSE);
675 if (svp && SvOK(*svp))
677 info->db_BT_compare = btree_compare ;
678 RETVAL->compare = newSVsv(*svp) ;
681 info->db_BT_compare = NULL ;
683 svp = hv_fetch(action, "prefix", 6, FALSE);
684 if (svp && SvOK(*svp))
686 info->db_BT_prefix = btree_prefix ;
687 RETVAL->prefix = newSVsv(*svp) ;
690 info->db_BT_prefix = NULL ;
692 svp = hv_fetch(action, "flags", 5, FALSE);
693 info->db_BT_flags = svp ? SvIV(*svp) : 0;
695 svp = hv_fetch(action, "cachesize", 9, FALSE);
696 info->db_BT_cachesize = svp ? SvIV(*svp) : 0;
698 #ifndef DB_VERSION_MAJOR
699 svp = hv_fetch(action, "minkeypage", 10, FALSE);
700 info->btree.minkeypage = svp ? SvIV(*svp) : 0;
702 svp = hv_fetch(action, "maxkeypage", 10, FALSE);
703 info->btree.maxkeypage = svp ? SvIV(*svp) : 0;
706 svp = hv_fetch(action, "psize", 5, FALSE);
707 info->db_BT_psize = svp ? SvIV(*svp) : 0;
709 svp = hv_fetch(action, "lorder", 6, FALSE);
710 info->db_BT_lorder = svp ? SvIV(*svp) : 0;
715 else if (sv_isa(sv, "DB_File::RECNOINFO"))
718 croak("DB_File can only tie an array to a DB_RECNO database");
720 RETVAL->type = DB_RECNO ;
721 openinfo = (void *)info ;
723 info->db_RE_flags = 0 ;
725 svp = hv_fetch(action, "flags", 5, FALSE);
726 info->db_RE_flags = (u_long) (svp ? SvIV(*svp) : 0);
728 svp = hv_fetch(action, "reclen", 6, FALSE);
729 info->db_RE_reclen = (size_t) (svp ? SvIV(*svp) : 0);
731 svp = hv_fetch(action, "cachesize", 9, FALSE);
732 info->db_RE_cachesize = (u_int) (svp ? SvIV(*svp) : 0);
734 svp = hv_fetch(action, "psize", 5, FALSE);
735 info->db_RE_psize = (u_int) (svp ? SvIV(*svp) : 0);
737 svp = hv_fetch(action, "lorder", 6, FALSE);
738 info->db_RE_lorder = (int) (svp ? SvIV(*svp) : 0);
740 #ifdef DB_VERSION_MAJOR
741 info->re_source = name ;
744 svp = hv_fetch(action, "bfname", 6, FALSE);
745 if (svp && SvOK(*svp)) {
746 char * ptr = SvPV(*svp,n_a) ;
747 #ifdef DB_VERSION_MAJOR
748 name = (char*) n_a ? ptr : NULL ;
750 info->db_RE_bfname = (char*) (n_a ? ptr : NULL) ;
754 #ifdef DB_VERSION_MAJOR
757 info->db_RE_bfname = NULL ;
760 svp = hv_fetch(action, "bval", 4, FALSE);
761 #ifdef DB_VERSION_MAJOR
762 if (svp && SvOK(*svp))
766 value = (int)*SvPV(*svp, n_a) ;
770 if (info->flags & DB_FIXEDLEN) {
771 info->re_pad = value ;
772 info->flags |= DB_PAD ;
775 info->re_delim = value ;
776 info->flags |= DB_DELIMITER ;
781 if (svp && SvOK(*svp))
784 info->db_RE_bval = (u_char)*SvPV(*svp, n_a) ;
786 info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ;
787 DB_flags(info->flags, DB_DELIMITER) ;
792 if (info->db_RE_flags & R_FIXEDLEN)
793 info->db_RE_bval = (u_char) ' ' ;
795 info->db_RE_bval = (u_char) '\n' ;
796 DB_flags(info->flags, DB_DELIMITER) ;
801 info->flags |= DB_RENUMBER ;
807 croak("type is not of type DB_File::HASHINFO, DB_File::BTREEINFO or DB_File::RECNOINFO");
811 /* OS2 Specific Code */
818 #ifdef DB_VERSION_MAJOR
824 /* Map 1.x flags to 2.x flags */
825 if ((flags & O_CREAT) == O_CREAT)
829 if ((flags & O_NONBLOCK) == O_NONBLOCK)
834 if (flags == O_RDONLY)
836 if ((flags & O_RDONLY) == O_RDONLY)
841 if ((flags & O_TRUNC) == O_TRUNC)
842 Flags |= DB_TRUNCATE ;
845 status = db_open(name, RETVAL->type, Flags, mode, NULL, openinfo, &RETVAL->dbp) ;
847 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
848 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor) ;
850 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor,
859 RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ;
870 croak("DB_File::%s not implemented on this architecture", s);
884 if (strEQ(name, "BTREEMAGIC"))
890 if (strEQ(name, "BTREEVERSION"))
900 if (strEQ(name, "DB_LOCK"))
906 if (strEQ(name, "DB_SHMEM"))
912 if (strEQ(name, "DB_TXN"))
926 if (strEQ(name, "HASHMAGIC"))
932 if (strEQ(name, "HASHVERSION"))
948 if (strEQ(name, "MAX_PAGE_NUMBER"))
949 #ifdef MAX_PAGE_NUMBER
950 return (U32)MAX_PAGE_NUMBER;
954 if (strEQ(name, "MAX_PAGE_OFFSET"))
955 #ifdef MAX_PAGE_OFFSET
956 return MAX_PAGE_OFFSET;
960 if (strEQ(name, "MAX_REC_NUMBER"))
961 #ifdef MAX_REC_NUMBER
962 return (U32)MAX_REC_NUMBER;
976 if (strEQ(name, "RET_ERROR"))
982 if (strEQ(name, "RET_SPECIAL"))
988 if (strEQ(name, "RET_SUCCESS"))
994 if (strEQ(name, "R_CURSOR"))
1000 if (strEQ(name, "R_DUP"))
1006 if (strEQ(name, "R_FIRST"))
1012 if (strEQ(name, "R_FIXEDLEN"))
1018 if (strEQ(name, "R_IAFTER"))
1024 if (strEQ(name, "R_IBEFORE"))
1030 if (strEQ(name, "R_LAST"))
1036 if (strEQ(name, "R_NEXT"))
1042 if (strEQ(name, "R_NOKEY"))
1048 if (strEQ(name, "R_NOOVERWRITE"))
1049 #ifdef R_NOOVERWRITE
1050 return R_NOOVERWRITE;
1054 if (strEQ(name, "R_PREV"))
1060 if (strEQ(name, "R_RECNOSYNC"))
1066 if (strEQ(name, "R_SETCURSOR"))
1072 if (strEQ(name, "R_SNAPSHOT"))
1106 MODULE = DB_File PACKAGE = DB_File PREFIX = db_
1112 empty.data = &zero ;
1113 empty.size = sizeof(recno_t) ;
1124 db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_HASH)
1131 char * name = (char *) NULL ;
1132 SV * sv = (SV *) NULL ;
1135 if (items >= 3 && SvOK(ST(2)))
1136 name = (char*) SvPV(ST(2), n_a) ;
1141 RETVAL = ParseOpenInfo(isHASH, name, flags, mode, sv) ;
1142 if (RETVAL->dbp == NULL)
1155 SvREFCNT_dec(db->hash) ;
1157 SvREFCNT_dec(db->compare) ;
1159 SvREFCNT_dec(db->prefix) ;
1161 #ifdef DB_VERSION_MAJOR
1168 db_DELETE(db, key, flags=0)
1186 RETVAL = (((db->dbp)->get)(db->dbp, TXN &key, &value, 0) == 0) ;
1192 db_FETCH(db, key, flags=0)
1202 /* RETVAL = ((db->dbp)->get)(db->dbp, TXN &key, &value, flags) ; */
1203 RETVAL = db_get(db, key, value, flags) ;
1204 ST(0) = sv_newmortal();
1205 OutputValue(ST(0), value)
1209 db_STORE(db, key, value, flags=0)
1230 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1231 ST(0) = sv_newmortal();
1232 OutputKey(ST(0), key) ;
1246 RETVAL = do_SEQ(db, key, value, R_NEXT) ;
1247 ST(0) = sv_newmortal();
1248 OutputKey(ST(0), key) ;
1252 # These would be nice for RECNO
1271 #ifdef DB_VERSION_MAJOR
1272 /* get the first value */
1273 RETVAL = do_SEQ(db, key, value, DB_FIRST) ;
1278 for (i = items-1 ; i > 0 ; --i)
1280 value.data = SvPV(ST(i), n_a) ;
1284 key.size = sizeof(int) ;
1285 #ifdef DB_VERSION_MAJOR
1286 RETVAL = (db->cursor->c_put)(db->cursor, &key, &value, DB_BEFORE) ;
1288 RETVAL = (Db->put)(Db, &key, &value, R_IBEFORE) ;
1311 /* First get the final value */
1312 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1313 ST(0) = sv_newmortal();
1317 /* the call to del will trash value, so take a copy now */
1318 OutputValue(ST(0), value) ;
1319 RETVAL = db_del(db, key, R_CURSOR) ;
1321 sv_setsv(ST(0), &PL_sv_undef);
1338 /* get the first value */
1339 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1340 ST(0) = sv_newmortal();
1344 /* the call to del will trash value, so take a copy now */
1345 OutputValue(ST(0), value) ;
1346 RETVAL = db_del(db, key, R_CURSOR) ;
1348 sv_setsv (ST(0), &PL_sv_undef) ;
1360 DBTKEY * keyptr = &key ;
1369 /* Set the Cursor to the Last element */
1370 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1375 #ifdef DB_VERSION_MAJOR
1376 for (i = 1 ; i < items ; ++i)
1379 ++ (* (int*)key.data) ;
1380 value.data = SvPV(ST(i), n_a) ;
1382 RETVAL = (Db->put)(Db, NULL, &key, &value, 0) ;
1387 for (i = items - 1 ; i > 0 ; --i)
1389 value.data = SvPV(ST(i), n_a) ;
1391 RETVAL = (Db->put)(Db, keyptr, &value, R_IAFTER) ;
1405 ALIAS: FETCHSIZE = 1
1408 RETVAL = GetArrayLength(db) ;
1414 # Now provide an interface to the rest of the DB functionality
1418 db_del(db, key, flags=0)
1424 RETVAL = db_del(db, key, flags) ;
1425 #ifdef DB_VERSION_MAJOR
1428 else if (RETVAL == DB_NOTFOUND)
1436 db_get(db, key, value, flags=0)
1444 RETVAL = db_get(db, key, value, flags) ;
1445 #ifdef DB_VERSION_MAJOR
1448 else if (RETVAL == DB_NOTFOUND)
1456 db_put(db, key, value, flags=0)
1463 RETVAL = db_put(db, key, value, flags) ;
1464 #ifdef DB_VERSION_MAJOR
1467 else if (RETVAL == DB_KEYEXIST)
1472 key if (flagSet(flags, R_IAFTER) || flagSet(flags, R_IBEFORE)) OutputKey(ST(1), key);
1480 #ifdef DB_VERSION_MAJOR
1482 status = (db->in_memory
1484 : ((db->dbp)->fd)(db->dbp, &RETVAL) ) ;
1488 RETVAL = (db->in_memory
1490 : ((db->dbp)->fd)(db->dbp) ) ;
1496 db_sync(db, flags=0)
1501 RETVAL = db_sync(db, flags) ;
1502 #ifdef DB_VERSION_MAJOR
1511 db_seq(db, key, value, flags)
1519 RETVAL = db_seq(db, key, value, flags);
1520 #ifdef DB_VERSION_MAJOR
1523 else if (RETVAL == DB_NOTFOUND)