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.
73 /* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
74 * shortly #included by the <db.h>) __attribute__ to the possibly
75 * already defined __attribute__, for example by GNUC or by Perl. */
79 /* If Perl has been compiled with Threads support,the symbol op will
80 be defined here. This clashes with a field name in db.h, so get rid of it.
93 #ifdef DB_VERSION_MAJOR
95 /* map version 2 features & constants onto their version 1 equivalent */
100 #define DB_Prefix_t size_t
105 #define DB_Hash_t u_int32_t
107 /* DBTYPE stays the same */
108 /* HASHINFO, RECNOINFO and BTREEINFO map to DB_INFO */
109 typedef DB_INFO INFO ;
111 /* version 2 has db_recno_t in place of recno_t */
112 typedef db_recno_t recno_t;
115 #define R_CURSOR DB_SET_RANGE
116 #define R_FIRST DB_FIRST
117 #define R_IAFTER DB_AFTER
118 #define R_IBEFORE DB_BEFORE
119 #define R_LAST DB_LAST
120 #define R_NEXT DB_NEXT
121 #define R_NOOVERWRITE DB_NOOVERWRITE
122 #define R_PREV DB_PREV
123 #define R_SETCURSOR 0
124 #define R_RECNOSYNC 0
125 #define R_FIXEDLEN DB_FIXEDLEN
128 #define db_HA_hash h_hash
129 #define db_HA_ffactor h_ffactor
130 #define db_HA_nelem h_nelem
131 #define db_HA_bsize db_pagesize
132 #define db_HA_cachesize db_cachesize
133 #define db_HA_lorder db_lorder
135 #define db_BT_compare bt_compare
136 #define db_BT_prefix bt_prefix
137 #define db_BT_flags flags
138 #define db_BT_psize db_pagesize
139 #define db_BT_cachesize db_cachesize
140 #define db_BT_lorder db_lorder
141 #define db_BT_maxkeypage
142 #define db_BT_minkeypage
145 #define db_RE_reclen re_len
146 #define db_RE_flags flags
147 #define db_RE_bval re_pad
148 #define db_RE_bfname re_source
149 #define db_RE_psize db_pagesize
150 #define db_RE_cachesize db_cachesize
151 #define db_RE_lorder db_lorder
155 #define do_SEQ(db, key, value, flag) (db->cursor->c_get)(db->cursor, &key, &value, flag)
158 #define DBT_flags(x) x.flags = 0
159 #define DB_flags(x, v) x |= v
161 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
162 #define flagSet(flags, bitmask) ((flags) & (bitmask))
164 #define flagSet(flags, bitmask) (((flags) & DB_OPFLAGS_MASK) == (bitmask))
167 #else /* db version 1.x */
180 #define DB_Prefix_t mDB_Prefix_t
187 #define DB_Hash_t mDB_Hash_t
190 #define db_HA_hash hash.hash
191 #define db_HA_ffactor hash.ffactor
192 #define db_HA_nelem hash.nelem
193 #define db_HA_bsize hash.bsize
194 #define db_HA_cachesize hash.cachesize
195 #define db_HA_lorder hash.lorder
197 #define db_BT_compare btree.compare
198 #define db_BT_prefix btree.prefix
199 #define db_BT_flags btree.flags
200 #define db_BT_psize btree.psize
201 #define db_BT_cachesize btree.cachesize
202 #define db_BT_lorder btree.lorder
203 #define db_BT_maxkeypage btree.maxkeypage
204 #define db_BT_minkeypage btree.minkeypage
206 #define db_RE_reclen recno.reclen
207 #define db_RE_flags recno.flags
208 #define db_RE_bval recno.bval
209 #define db_RE_bfname recno.bfname
210 #define db_RE_psize recno.psize
211 #define db_RE_cachesize recno.cachesize
212 #define db_RE_lorder recno.lorder
216 #define do_SEQ(db, key, value, flag) (db->dbp->seq)(db->dbp, &key, &value, flag)
218 #define DB_flags(x, v)
219 #define flagSet(flags, bitmask) ((flags) & (bitmask))
221 #endif /* db version 1 */
225 #define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, TXN &key, flags)
226 #define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, flags)
227 #define db_FETCH(db, key, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
229 #define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags)
230 #define db_get(db, key, value, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
232 #ifdef DB_VERSION_MAJOR
233 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp, 0)
234 #define db_close(db) ((db->dbp)->close)(db->dbp, 0)
235 #define db_del(db, key, flags) (flagSet(flags, R_CURSOR) \
236 ? ((db->cursor)->c_del)(db->cursor, 0) \
237 : ((db->dbp)->del)(db->dbp, NULL, &key, flags) )
241 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp)
242 #define db_close(db) ((db->dbp)->close)(db->dbp)
243 #define db_del(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags)
244 #define db_put(db, key, value, flags) ((db->dbp)->put)(db->dbp, &key, &value, flags)
249 #define db_seq(db, key, value, flags) do_SEQ(db, key, value, flags)
259 #ifdef DB_VERSION_MAJOR
264 typedef DB_File_type * DB_File ;
267 #define my_sv_setpvn(sv, d, s) sv_setpvn(sv, (s ? d : (void*)""), s)
269 #define OutputValue(arg, name) \
270 { if (RETVAL == 0) { \
271 my_sv_setpvn(arg, name.data, name.size) ; \
275 #define OutputKey(arg, name) \
278 if (db->type != DB_RECNO) { \
279 my_sv_setpvn(arg, name.data, name.size); \
282 sv_setiv(arg, (I32)*(I32*)name.data - 1); \
287 /* Internal Global Data */
288 static recno_t Value ;
289 static recno_t zero = 0 ;
290 static DB_File CurrentDB ;
291 static DBTKEY empty ;
293 #ifdef DB_VERSION_MAJOR
296 db_put(db, key, value, flags)
305 if (flagSet(flags, R_CURSOR)) {
306 status = ((db->cursor)->c_del)(db->cursor, 0);
310 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
313 flags &= ~DB_OPFLAGS_MASK ;
318 return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;
322 #endif /* DB_VERSION_MAJOR */
327 SV * ver_sv = perl_get_sv("DB_File::db_version", TRUE) ;
328 #ifdef DB_VERSION_MAJOR
329 int Major, Minor, Patch ;
331 (void)db_version(&Major, &Minor, &Patch) ;
333 /* check that libdb is recent enough */
334 if (Major == 2 && Minor == 0 && Patch < 5)
335 croak("DB_File needs Berkeley DB 2.0.5 or greater, you have %d.%d.%d\n",
336 Major, Minor, Patch) ;
339 sv_setpvf(ver_sv, "%d.%d", Major, Minor) ;
343 sprintf(buffer, "%d.%d", Major, Minor) ;
344 sv_setpv(ver_sv, buffer) ;
349 sv_setiv(ver_sv, 1) ;
356 btree_compare(key1, key2)
361 void * data1, * data2 ;
368 /* As newSVpv will assume that the data pointer is a null terminated C
369 string if the size parameter is 0, make sure that data points to an
370 empty string if the length is 0
382 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
383 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
386 count = perl_call_sv(CurrentDB->compare, G_SCALAR);
391 croak ("DB_File btree_compare: expected 1 return value from compare sub, got %d\n", count) ;
403 btree_prefix(key1, key2)
408 void * data1, * data2 ;
415 /* As newSVpv will assume that the data pointer is a null terminated C
416 string if the size parameter is 0, make sure that data points to an
417 empty string if the length is 0
429 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
430 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
433 count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
438 croak ("DB_File btree_prefix: expected 1 return value from prefix sub, got %d\n", count) ;
461 /* DGH - Next two lines added to fix corrupted stack problem */
467 XPUSHs(sv_2mortal(newSVpv((char*)data,size)));
470 count = perl_call_sv(CurrentDB->hash, G_SCALAR);
475 croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ;
493 printf ("HASH Info\n") ;
494 printf (" hash = %s\n",
495 (hash->db_HA_hash != NULL ? "redefined" : "default")) ;
496 printf (" bsize = %d\n", hash->db_HA_bsize) ;
497 printf (" ffactor = %d\n", hash->db_HA_ffactor) ;
498 printf (" nelem = %d\n", hash->db_HA_nelem) ;
499 printf (" cachesize = %d\n", hash->db_HA_cachesize) ;
500 printf (" lorder = %d\n", hash->db_HA_lorder) ;
508 printf ("RECNO Info\n") ;
509 printf (" flags = %d\n", recno->db_RE_flags) ;
510 printf (" cachesize = %d\n", recno->db_RE_cachesize) ;
511 printf (" psize = %d\n", recno->db_RE_psize) ;
512 printf (" lorder = %d\n", recno->db_RE_lorder) ;
513 printf (" reclen = %ul\n", (unsigned long)recno->db_RE_reclen) ;
514 printf (" bval = %d 0x%x\n", recno->db_RE_bval, recno->db_RE_bval) ;
515 printf (" bfname = %d [%s]\n", recno->db_RE_bfname, recno->db_RE_bfname) ;
522 printf ("BTREE Info\n") ;
523 printf (" compare = %s\n",
524 (btree->db_BT_compare ? "redefined" : "default")) ;
525 printf (" prefix = %s\n",
526 (btree->db_BT_prefix ? "redefined" : "default")) ;
527 printf (" flags = %d\n", btree->db_BT_flags) ;
528 printf (" cachesize = %d\n", btree->db_BT_cachesize) ;
529 printf (" psize = %d\n", btree->db_BT_psize) ;
530 #ifndef DB_VERSION_MAJOR
531 printf (" maxkeypage = %d\n", btree->db_BT_maxkeypage) ;
532 printf (" minkeypage = %d\n", btree->db_BT_minkeypage) ;
534 printf (" lorder = %d\n", btree->db_BT_lorder) ;
539 #define PrintRecno(recno)
540 #define PrintHash(hash)
541 #define PrintBtree(btree)
556 RETVAL = do_SEQ(db, key, value, R_LAST) ;
558 RETVAL = *(I32 *)key.data ;
559 else /* No key means empty file */
562 return ((I32)RETVAL) ;
566 GetRecnoKey(db, value)
571 /* Get the length of the array */
572 I32 length = GetArrayLength(db) ;
574 /* check for attempt to write before start of array */
575 if (length + value + 1 <= 0)
576 croak("Modification of non-creatable array value attempted, subscript %ld", (long)value) ;
578 value = length + value + 1 ;
587 ParseOpenInfo(isHASH, name, flags, mode, sv)
596 DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ;
597 void * openinfo = NULL ;
598 INFO * info = &RETVAL->info ;
601 /* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
602 Zero(RETVAL, 1, DB_File_type) ;
604 /* Default to HASH */
605 RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
606 RETVAL->type = DB_HASH ;
608 /* DGH - Next line added to avoid SEGV on existing hash DB */
611 /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */
612 RETVAL->in_memory = (name == NULL) ;
617 croak ("type parameter is not a reference") ;
619 svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ;
620 if (svp && SvOK(*svp))
621 action = (HV*) SvRV(*svp) ;
623 croak("internal error") ;
625 if (sv_isa(sv, "DB_File::HASHINFO"))
629 croak("DB_File can only tie an associative array to a DB_HASH database") ;
631 RETVAL->type = DB_HASH ;
632 openinfo = (void*)info ;
634 svp = hv_fetch(action, "hash", 4, FALSE);
636 if (svp && SvOK(*svp))
638 info->db_HA_hash = hash_cb ;
639 RETVAL->hash = newSVsv(*svp) ;
642 info->db_HA_hash = NULL ;
644 svp = hv_fetch(action, "ffactor", 7, FALSE);
645 info->db_HA_ffactor = svp ? SvIV(*svp) : 0;
647 svp = hv_fetch(action, "nelem", 5, FALSE);
648 info->db_HA_nelem = svp ? SvIV(*svp) : 0;
650 svp = hv_fetch(action, "bsize", 5, FALSE);
651 info->db_HA_bsize = svp ? SvIV(*svp) : 0;
653 svp = hv_fetch(action, "cachesize", 9, FALSE);
654 info->db_HA_cachesize = svp ? SvIV(*svp) : 0;
656 svp = hv_fetch(action, "lorder", 6, FALSE);
657 info->db_HA_lorder = svp ? SvIV(*svp) : 0;
661 else if (sv_isa(sv, "DB_File::BTREEINFO"))
664 croak("DB_File can only tie an associative array to a DB_BTREE database");
666 RETVAL->type = DB_BTREE ;
667 openinfo = (void*)info ;
669 svp = hv_fetch(action, "compare", 7, FALSE);
670 if (svp && SvOK(*svp))
672 info->db_BT_compare = btree_compare ;
673 RETVAL->compare = newSVsv(*svp) ;
676 info->db_BT_compare = NULL ;
678 svp = hv_fetch(action, "prefix", 6, FALSE);
679 if (svp && SvOK(*svp))
681 info->db_BT_prefix = btree_prefix ;
682 RETVAL->prefix = newSVsv(*svp) ;
685 info->db_BT_prefix = NULL ;
687 svp = hv_fetch(action, "flags", 5, FALSE);
688 info->db_BT_flags = svp ? SvIV(*svp) : 0;
690 svp = hv_fetch(action, "cachesize", 9, FALSE);
691 info->db_BT_cachesize = svp ? SvIV(*svp) : 0;
693 #ifndef DB_VERSION_MAJOR
694 svp = hv_fetch(action, "minkeypage", 10, FALSE);
695 info->btree.minkeypage = svp ? SvIV(*svp) : 0;
697 svp = hv_fetch(action, "maxkeypage", 10, FALSE);
698 info->btree.maxkeypage = svp ? SvIV(*svp) : 0;
701 svp = hv_fetch(action, "psize", 5, FALSE);
702 info->db_BT_psize = svp ? SvIV(*svp) : 0;
704 svp = hv_fetch(action, "lorder", 6, FALSE);
705 info->db_BT_lorder = svp ? SvIV(*svp) : 0;
710 else if (sv_isa(sv, "DB_File::RECNOINFO"))
713 croak("DB_File can only tie an array to a DB_RECNO database");
715 RETVAL->type = DB_RECNO ;
716 openinfo = (void *)info ;
718 info->db_RE_flags = 0 ;
720 svp = hv_fetch(action, "flags", 5, FALSE);
721 info->db_RE_flags = (u_long) (svp ? SvIV(*svp) : 0);
723 svp = hv_fetch(action, "reclen", 6, FALSE);
724 info->db_RE_reclen = (size_t) (svp ? SvIV(*svp) : 0);
726 svp = hv_fetch(action, "cachesize", 9, FALSE);
727 info->db_RE_cachesize = (u_int) (svp ? SvIV(*svp) : 0);
729 svp = hv_fetch(action, "psize", 5, FALSE);
730 info->db_RE_psize = (u_int) (svp ? SvIV(*svp) : 0);
732 svp = hv_fetch(action, "lorder", 6, FALSE);
733 info->db_RE_lorder = (int) (svp ? SvIV(*svp) : 0);
735 #ifdef DB_VERSION_MAJOR
736 info->re_source = name ;
739 svp = hv_fetch(action, "bfname", 6, FALSE);
740 if (svp && SvOK(*svp)) {
741 char * ptr = SvPV(*svp,n_a) ;
742 #ifdef DB_VERSION_MAJOR
743 name = (char*) n_a ? ptr : NULL ;
745 info->db_RE_bfname = (char*) (n_a ? ptr : NULL) ;
749 #ifdef DB_VERSION_MAJOR
752 info->db_RE_bfname = NULL ;
755 svp = hv_fetch(action, "bval", 4, FALSE);
756 #ifdef DB_VERSION_MAJOR
757 if (svp && SvOK(*svp))
761 value = (int)*SvPV(*svp, n_a) ;
765 if (info->flags & DB_FIXEDLEN) {
766 info->re_pad = value ;
767 info->flags |= DB_PAD ;
770 info->re_delim = value ;
771 info->flags |= DB_DELIMITER ;
776 if (svp && SvOK(*svp))
779 info->db_RE_bval = (u_char)*SvPV(*svp, n_a) ;
781 info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ;
782 DB_flags(info->flags, DB_DELIMITER) ;
787 if (info->db_RE_flags & R_FIXEDLEN)
788 info->db_RE_bval = (u_char) ' ' ;
790 info->db_RE_bval = (u_char) '\n' ;
791 DB_flags(info->flags, DB_DELIMITER) ;
796 info->flags |= DB_RENUMBER ;
802 croak("type is not of type DB_File::HASHINFO, DB_File::BTREEINFO or DB_File::RECNOINFO");
806 /* OS2 Specific Code */
813 #ifdef DB_VERSION_MAJOR
819 /* Map 1.x flags to 2.x flags */
820 if ((flags & O_CREAT) == O_CREAT)
824 if ((flags & O_NONBLOCK) == O_NONBLOCK)
829 if (flags == O_RDONLY)
831 if ((flags & O_RDONLY) == O_RDONLY)
836 if ((flags & O_TRUNC) == O_TRUNC)
837 Flags |= DB_TRUNCATE ;
840 status = db_open(name, RETVAL->type, Flags, mode, NULL, openinfo, &RETVAL->dbp) ;
842 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
843 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor) ;
845 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor,
854 RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ;
865 croak("DB_File::%s not implemented on this architecture", s);
879 if (strEQ(name, "BTREEMAGIC"))
885 if (strEQ(name, "BTREEVERSION"))
895 if (strEQ(name, "DB_LOCK"))
901 if (strEQ(name, "DB_SHMEM"))
907 if (strEQ(name, "DB_TXN"))
921 if (strEQ(name, "HASHMAGIC"))
927 if (strEQ(name, "HASHVERSION"))
943 if (strEQ(name, "MAX_PAGE_NUMBER"))
944 #ifdef MAX_PAGE_NUMBER
945 return (U32)MAX_PAGE_NUMBER;
949 if (strEQ(name, "MAX_PAGE_OFFSET"))
950 #ifdef MAX_PAGE_OFFSET
951 return MAX_PAGE_OFFSET;
955 if (strEQ(name, "MAX_REC_NUMBER"))
956 #ifdef MAX_REC_NUMBER
957 return (U32)MAX_REC_NUMBER;
971 if (strEQ(name, "RET_ERROR"))
977 if (strEQ(name, "RET_SPECIAL"))
983 if (strEQ(name, "RET_SUCCESS"))
989 if (strEQ(name, "R_CURSOR"))
995 if (strEQ(name, "R_DUP"))
1001 if (strEQ(name, "R_FIRST"))
1007 if (strEQ(name, "R_FIXEDLEN"))
1013 if (strEQ(name, "R_IAFTER"))
1019 if (strEQ(name, "R_IBEFORE"))
1025 if (strEQ(name, "R_LAST"))
1031 if (strEQ(name, "R_NEXT"))
1037 if (strEQ(name, "R_NOKEY"))
1043 if (strEQ(name, "R_NOOVERWRITE"))
1044 #ifdef R_NOOVERWRITE
1045 return R_NOOVERWRITE;
1049 if (strEQ(name, "R_PREV"))
1055 if (strEQ(name, "R_RECNOSYNC"))
1061 if (strEQ(name, "R_SETCURSOR"))
1067 if (strEQ(name, "R_SNAPSHOT"))
1101 MODULE = DB_File PACKAGE = DB_File PREFIX = db_
1107 empty.data = &zero ;
1108 empty.size = sizeof(recno_t) ;
1119 db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_HASH)
1126 char * name = (char *) NULL ;
1127 SV * sv = (SV *) NULL ;
1130 if (items >= 3 && SvOK(ST(2)))
1131 name = (char*) SvPV(ST(2), n_a) ;
1136 RETVAL = ParseOpenInfo(isHASH, name, flags, mode, sv) ;
1137 if (RETVAL->dbp == NULL)
1150 SvREFCNT_dec(db->hash) ;
1152 SvREFCNT_dec(db->compare) ;
1154 SvREFCNT_dec(db->prefix) ;
1156 #ifdef DB_VERSION_MAJOR
1163 db_DELETE(db, key, flags=0)
1181 RETVAL = (((db->dbp)->get)(db->dbp, TXN &key, &value, 0) == 0) ;
1187 db_FETCH(db, key, flags=0)
1197 /* RETVAL = ((db->dbp)->get)(db->dbp, TXN &key, &value, flags) ; */
1198 RETVAL = db_get(db, key, value, flags) ;
1199 ST(0) = sv_newmortal();
1200 OutputValue(ST(0), value)
1204 db_STORE(db, key, value, flags=0)
1225 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1226 ST(0) = sv_newmortal();
1227 OutputKey(ST(0), key) ;
1241 RETVAL = do_SEQ(db, key, value, R_NEXT) ;
1242 ST(0) = sv_newmortal();
1243 OutputKey(ST(0), key) ;
1247 # These would be nice for RECNO
1266 #ifdef DB_VERSION_MAJOR
1267 /* get the first value */
1268 RETVAL = do_SEQ(db, key, value, DB_FIRST) ;
1273 for (i = items-1 ; i > 0 ; --i)
1275 value.data = SvPV(ST(i), n_a) ;
1279 key.size = sizeof(int) ;
1280 #ifdef DB_VERSION_MAJOR
1281 RETVAL = (db->cursor->c_put)(db->cursor, &key, &value, DB_BEFORE) ;
1283 RETVAL = (Db->put)(Db, &key, &value, R_IBEFORE) ;
1306 /* First get the final value */
1307 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1308 ST(0) = sv_newmortal();
1312 /* the call to del will trash value, so take a copy now */
1313 OutputValue(ST(0), value) ;
1314 RETVAL = db_del(db, key, R_CURSOR) ;
1316 sv_setsv(ST(0), &PL_sv_undef);
1333 /* get the first value */
1334 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1335 ST(0) = sv_newmortal();
1339 /* the call to del will trash value, so take a copy now */
1340 OutputValue(ST(0), value) ;
1341 RETVAL = db_del(db, key, R_CURSOR) ;
1343 sv_setsv (ST(0), &PL_sv_undef) ;
1355 DBTKEY * keyptr = &key ;
1364 /* Set the Cursor to the Last element */
1365 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1370 #ifdef DB_VERSION_MAJOR
1371 for (i = 1 ; i < items ; ++i)
1374 ++ (* (int*)key.data) ;
1375 value.data = SvPV(ST(i), n_a) ;
1377 RETVAL = (Db->put)(Db, NULL, &key, &value, 0) ;
1382 for (i = items - 1 ; i > 0 ; --i)
1384 value.data = SvPV(ST(i), n_a) ;
1386 RETVAL = (Db->put)(Db, keyptr, &value, R_IAFTER) ;
1400 ALIAS: FETCHSIZE = 1
1403 RETVAL = GetArrayLength(db) ;
1409 # Now provide an interface to the rest of the DB functionality
1413 db_del(db, key, flags=0)
1419 RETVAL = db_del(db, key, flags) ;
1420 #ifdef DB_VERSION_MAJOR
1423 else if (RETVAL == DB_NOTFOUND)
1431 db_get(db, key, value, flags=0)
1439 RETVAL = db_get(db, key, value, flags) ;
1440 #ifdef DB_VERSION_MAJOR
1443 else if (RETVAL == DB_NOTFOUND)
1451 db_put(db, key, value, flags=0)
1458 RETVAL = db_put(db, key, value, flags) ;
1459 #ifdef DB_VERSION_MAJOR
1462 else if (RETVAL == DB_KEYEXIST)
1467 key if (flagSet(flags, R_IAFTER) || flagSet(flags, R_IBEFORE)) OutputKey(ST(1), key);
1475 #ifdef DB_VERSION_MAJOR
1477 status = (db->in_memory
1479 : ((db->dbp)->fd)(db->dbp, &RETVAL) ) ;
1483 RETVAL = (db->in_memory
1485 : ((db->dbp)->fd)(db->dbp) ) ;
1491 db_sync(db, flags=0)
1496 RETVAL = db_sync(db, flags) ;
1497 #ifdef DB_VERSION_MAJOR
1506 db_seq(db, key, value, flags)
1514 RETVAL = db_seq(db, key, value, flags);
1515 #ifdef DB_VERSION_MAJOR
1518 else if (RETVAL == DB_NOTFOUND)