3 DB_File.xs -- Perl 5 interface to Berkeley DB
5 written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
6 last modified 20th Nov 1997
9 All comments/suggestions/problems are welcome
11 Copyright (c) 1995, 1996, 1997 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
62 /* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
63 * shortly #included by the <db.h>) __attribute__ to the possibly
64 * already defined __attribute__, for example by GNUC or by Perl. */
76 #ifdef DB_VERSION_MAJOR
78 /* map version 2 features & constants onto their version 1 equivalent */
83 #define DB_Prefix_t size_t
88 #define DB_Hash_t u_int32_t
90 /* DBTYPE stays the same */
91 /* HASHINFO, RECNOINFO and BTREEINFO map to DB_INFO */
92 typedef DB_INFO INFO ;
94 /* version 2 has db_recno_t in place of recno_t */
95 typedef db_recno_t recno_t;
98 #define R_CURSOR DB_SET_RANGE
99 #define R_FIRST DB_FIRST
100 #define R_IAFTER DB_AFTER
101 #define R_IBEFORE DB_BEFORE
102 #define R_LAST DB_LAST
103 #define R_NEXT DB_NEXT
104 #define R_NOOVERWRITE DB_NOOVERWRITE
105 #define R_PREV DB_PREV
106 #define R_SETCURSOR 0
107 #define R_RECNOSYNC 0
108 #define R_FIXEDLEN DB_FIXEDLEN
111 #define db_HA_hash h_hash
112 #define db_HA_ffactor h_ffactor
113 #define db_HA_nelem h_nelem
114 #define db_HA_bsize db_pagesize
115 #define db_HA_cachesize db_cachesize
116 #define db_HA_lorder db_lorder
118 #define db_BT_compare bt_compare
119 #define db_BT_prefix bt_prefix
120 #define db_BT_flags flags
121 #define db_BT_psize db_pagesize
122 #define db_BT_cachesize db_cachesize
123 #define db_BT_lorder db_lorder
124 #define db_BT_maxkeypage
125 #define db_BT_minkeypage
128 #define db_RE_reclen re_len
129 #define db_RE_flags flags
130 #define db_RE_bval re_pad
131 #define db_RE_bfname re_source
132 #define db_RE_psize db_pagesize
133 #define db_RE_cachesize db_cachesize
134 #define db_RE_lorder db_lorder
138 #define do_SEQ(db, key, value, flag) (db->cursor->c_get)(db->cursor, &key, &value, flag)
141 #define DBT_flags(x) x.flags = 0
142 #define DB_flags(x, v) x |= v
144 #else /* db version 1.x */
157 #define DB_Prefix_t mDB_Prefix_t
164 #define DB_Hash_t mDB_Hash_t
167 #define db_HA_hash hash.hash
168 #define db_HA_ffactor hash.ffactor
169 #define db_HA_nelem hash.nelem
170 #define db_HA_bsize hash.bsize
171 #define db_HA_cachesize hash.cachesize
172 #define db_HA_lorder hash.lorder
174 #define db_BT_compare btree.compare
175 #define db_BT_prefix btree.prefix
176 #define db_BT_flags btree.flags
177 #define db_BT_psize btree.psize
178 #define db_BT_cachesize btree.cachesize
179 #define db_BT_lorder btree.lorder
180 #define db_BT_maxkeypage btree.maxkeypage
181 #define db_BT_minkeypage btree.minkeypage
183 #define db_RE_reclen recno.reclen
184 #define db_RE_flags recno.flags
185 #define db_RE_bval recno.bval
186 #define db_RE_bfname recno.bfname
187 #define db_RE_psize recno.psize
188 #define db_RE_cachesize recno.cachesize
189 #define db_RE_lorder recno.lorder
193 #define do_SEQ(db, key, value, flag) (db->dbp->seq)(db->dbp, &key, &value, flag)
195 #define DB_flags(x, v)
197 #endif /* db version 1 */
201 #define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, TXN &key, flags)
202 #define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, flags)
203 #define db_FETCH(db, key, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
205 #define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags)
206 #define db_get(db, key, value, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
207 #ifdef DB_VERSION_MAJOR
208 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp, 0)
209 #define db_close(db) ((db->dbp)->close)(db->dbp, 0)
210 #define db_del(db, key, flags) ((flags & R_CURSOR) \
211 ? ((db->cursor)->c_del)(db->cursor, 0) \
212 : ((db->dbp)->del)(db->dbp, NULL, &key, flags) )
216 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp)
217 #define db_close(db) ((db->dbp)->close)(db->dbp)
218 #define db_del(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags)
219 #define db_put(db, key, value, flags) ((db->dbp)->put)(db->dbp, &key, &value, flags)
223 #define db_seq(db, key, value, flags) do_SEQ(db, key, value, flags)
233 #ifdef DB_VERSION_MAJOR
238 typedef DB_File_type * DB_File ;
242 #define OutputValue(arg, name) \
243 { if (RETVAL == 0) { \
244 sv_setpvn(arg, name.data, name.size) ; \
248 #define OutputKey(arg, name) \
251 if (db->type != DB_RECNO) { \
252 sv_setpvn(arg, name.data, name.size); \
255 sv_setiv(arg, (I32)*(I32*)name.data - 1); \
259 /* Internal Global Data */
260 static recno_t Value ;
261 static recno_t zero = 0 ;
262 static DB_File CurrentDB ;
263 static DBTKEY empty ;
265 #ifdef DB_VERSION_MAJOR
268 db_put(db, key, value, flags)
277 if (flags & R_CURSOR) {
278 status = ((db->cursor)->c_del)(db->cursor, 0);
285 return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;
289 #endif /* DB_VERSION_MAJOR */
294 SV * ver_sv = perl_get_sv("DB_File::db_version", TRUE) ;
295 #ifdef DB_VERSION_MAJOR
296 int Major, Minor, Patch ;
298 (void)db_version(&Major, &Minor, &Patch) ;
300 /* check that libdb is recent enough */
301 if (Major == 2 && Minor == 0 && Patch < 5)
302 croak("DB_File needs Berkeley DB 2.0.5 or greater, you have %d.%d.%d\n",
303 Major, Minor, Patch) ;
306 sv_setpvf(ver_sv, "%d.%d", Major, Minor) ;
310 sprintf(buffer, "%d.%d", Major, Minor) ;
311 sv_setpv(ver_sv, buffer) ;
316 sv_setiv(ver_sv, 1) ;
323 btree_compare(key1, key2)
328 void * data1, * data2 ;
335 /* As newSVpv will assume that the data pointer is a null terminated C
336 string if the size parameter is 0, make sure that data points to an
337 empty string if the length is 0
349 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
350 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
353 count = perl_call_sv(CurrentDB->compare, G_SCALAR);
358 croak ("DB_File btree_compare: expected 1 return value from compare sub, got %d\n", count) ;
370 btree_prefix(key1, key2)
375 void * data1, * data2 ;
382 /* As newSVpv will assume that the data pointer is a null terminated C
383 string if the size parameter is 0, make sure that data points to an
384 empty string if the length is 0
396 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
397 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
400 count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
405 croak ("DB_File btree_prefix: expected 1 return value from prefix sub, got %d\n", count) ;
428 /* DGH - Next two lines added to fix corrupted stack problem */
434 XPUSHs(sv_2mortal(newSVpv((char*)data,size)));
437 count = perl_call_sv(CurrentDB->hash, G_SCALAR);
442 croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ;
460 printf ("HASH Info\n") ;
461 printf (" hash = %s\n",
462 (hash->db_HA_hash != NULL ? "redefined" : "default")) ;
463 printf (" bsize = %d\n", hash->db_HA_bsize) ;
464 printf (" ffactor = %d\n", hash->db_HA_ffactor) ;
465 printf (" nelem = %d\n", hash->db_HA_nelem) ;
466 printf (" cachesize = %d\n", hash->db_HA_cachesize) ;
467 printf (" lorder = %d\n", hash->db_HA_lorder) ;
475 printf ("RECNO Info\n") ;
476 printf (" flags = %d\n", recno->db_RE_flags) ;
477 printf (" cachesize = %d\n", recno->db_RE_cachesize) ;
478 printf (" psize = %d\n", recno->db_RE_psize) ;
479 printf (" lorder = %d\n", recno->db_RE_lorder) ;
480 printf (" reclen = %ul\n", (unsigned long)recno->db_RE_reclen) ;
481 printf (" bval = %d 0x%x\n", recno->db_RE_bval, recno->db_RE_bval) ;
482 printf (" bfname = %d [%s]\n", recno->db_RE_bfname, recno->db_RE_bfname) ;
489 printf ("BTREE Info\n") ;
490 printf (" compare = %s\n",
491 (btree->db_BT_compare ? "redefined" : "default")) ;
492 printf (" prefix = %s\n",
493 (btree->db_BT_prefix ? "redefined" : "default")) ;
494 printf (" flags = %d\n", btree->db_BT_flags) ;
495 printf (" cachesize = %d\n", btree->db_BT_cachesize) ;
496 printf (" psize = %d\n", btree->db_BT_psize) ;
497 #ifndef DB_VERSION_MAJOR
498 printf (" maxkeypage = %d\n", btree->db_BT_maxkeypage) ;
499 printf (" minkeypage = %d\n", btree->db_BT_minkeypage) ;
501 printf (" lorder = %d\n", btree->db_BT_lorder) ;
506 #define PrintRecno(recno)
507 #define PrintHash(hash)
508 #define PrintBtree(btree)
523 RETVAL = do_SEQ(db, key, value, R_LAST) ;
525 RETVAL = *(I32 *)key.data ;
526 else /* No key means empty file */
529 return ((I32)RETVAL) ;
533 GetRecnoKey(db, value)
538 /* Get the length of the array */
539 I32 length = GetArrayLength(db) ;
541 /* check for attempt to write before start of array */
542 if (length + value + 1 <= 0)
543 croak("Modification of non-creatable array value attempted, subscript %ld", (long)value) ;
545 value = length + value + 1 ;
554 ParseOpenInfo(isHASH, name, flags, mode, sv)
564 void * openinfo = NULL ;
567 /* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
568 Newz(777, RETVAL, 1, DB_File_type) ;
569 info = &RETVAL->info ;
571 /* Default to HASH */
572 RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
573 RETVAL->type = DB_HASH ;
575 /* DGH - Next line added to avoid SEGV on existing hash DB */
578 /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */
579 RETVAL->in_memory = (name == NULL) ;
584 croak ("type parameter is not a reference") ;
586 svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ;
587 if (svp && SvOK(*svp))
588 action = (HV*) SvRV(*svp) ;
590 croak("internal error") ;
592 if (sv_isa(sv, "DB_File::HASHINFO"))
596 croak("DB_File can only tie an associative array to a DB_HASH database") ;
598 RETVAL->type = DB_HASH ;
599 openinfo = (void*)info ;
601 svp = hv_fetch(action, "hash", 4, FALSE);
603 if (svp && SvOK(*svp))
605 info->db_HA_hash = hash_cb ;
606 RETVAL->hash = newSVsv(*svp) ;
609 info->db_HA_hash = NULL ;
611 svp = hv_fetch(action, "ffactor", 7, FALSE);
612 info->db_HA_ffactor = svp ? SvIV(*svp) : 0;
614 svp = hv_fetch(action, "nelem", 5, FALSE);
615 info->db_HA_nelem = svp ? SvIV(*svp) : 0;
617 svp = hv_fetch(action, "bsize", 5, FALSE);
618 info->db_HA_bsize = svp ? SvIV(*svp) : 0;
620 svp = hv_fetch(action, "cachesize", 9, FALSE);
621 info->db_HA_cachesize = svp ? SvIV(*svp) : 0;
623 svp = hv_fetch(action, "lorder", 6, FALSE);
624 info->db_HA_lorder = svp ? SvIV(*svp) : 0;
628 else if (sv_isa(sv, "DB_File::BTREEINFO"))
631 croak("DB_File can only tie an associative array to a DB_BTREE database");
633 RETVAL->type = DB_BTREE ;
634 openinfo = (void*)info ;
636 svp = hv_fetch(action, "compare", 7, FALSE);
637 if (svp && SvOK(*svp))
639 info->db_BT_compare = btree_compare ;
640 RETVAL->compare = newSVsv(*svp) ;
643 info->db_BT_compare = NULL ;
645 svp = hv_fetch(action, "prefix", 6, FALSE);
646 if (svp && SvOK(*svp))
648 info->db_BT_prefix = btree_prefix ;
649 RETVAL->prefix = newSVsv(*svp) ;
652 info->db_BT_prefix = NULL ;
654 svp = hv_fetch(action, "flags", 5, FALSE);
655 info->db_BT_flags = svp ? SvIV(*svp) : 0;
657 svp = hv_fetch(action, "cachesize", 9, FALSE);
658 info->db_BT_cachesize = svp ? SvIV(*svp) : 0;
660 #ifndef DB_VERSION_MAJOR
661 svp = hv_fetch(action, "minkeypage", 10, FALSE);
662 info->btree.minkeypage = svp ? SvIV(*svp) : 0;
664 svp = hv_fetch(action, "maxkeypage", 10, FALSE);
665 info->btree.maxkeypage = svp ? SvIV(*svp) : 0;
668 svp = hv_fetch(action, "psize", 5, FALSE);
669 info->db_BT_psize = svp ? SvIV(*svp) : 0;
671 svp = hv_fetch(action, "lorder", 6, FALSE);
672 info->db_BT_lorder = svp ? SvIV(*svp) : 0;
677 else if (sv_isa(sv, "DB_File::RECNOINFO"))
680 croak("DB_File can only tie an array to a DB_RECNO database");
682 RETVAL->type = DB_RECNO ;
683 openinfo = (void *)info ;
685 info->db_RE_flags = 0 ;
687 svp = hv_fetch(action, "flags", 5, FALSE);
688 info->db_RE_flags = (u_long) (svp ? SvIV(*svp) : 0);
690 svp = hv_fetch(action, "reclen", 6, FALSE);
691 info->db_RE_reclen = (size_t) (svp ? SvIV(*svp) : 0);
693 svp = hv_fetch(action, "cachesize", 9, FALSE);
694 info->db_RE_cachesize = (u_int) (svp ? SvIV(*svp) : 0);
696 svp = hv_fetch(action, "psize", 5, FALSE);
697 info->db_RE_psize = (u_int) (svp ? SvIV(*svp) : 0);
699 svp = hv_fetch(action, "lorder", 6, FALSE);
700 info->db_RE_lorder = (int) (svp ? SvIV(*svp) : 0);
702 #ifdef DB_VERSION_MAJOR
703 info->re_source = name ;
706 svp = hv_fetch(action, "bfname", 6, FALSE);
707 if (svp && SvOK(*svp)) {
708 char * ptr = SvPV(*svp,na) ;
709 #ifdef DB_VERSION_MAJOR
710 name = (char*) na ? ptr : NULL ;
712 info->db_RE_bfname = (char*) (na ? ptr : NULL) ;
716 #ifdef DB_VERSION_MAJOR
719 info->db_RE_bfname = NULL ;
722 svp = hv_fetch(action, "bval", 4, FALSE);
723 #ifdef DB_VERSION_MAJOR
724 if (svp && SvOK(*svp))
728 value = (int)*SvPV(*svp, na) ;
732 if (info->flags & DB_FIXEDLEN) {
733 info->re_pad = value ;
734 info->flags |= DB_PAD ;
737 info->re_delim = value ;
738 info->flags |= DB_DELIMITER ;
743 if (svp && SvOK(*svp))
746 info->db_RE_bval = (u_char)*SvPV(*svp, na) ;
748 info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ;
749 DB_flags(info->flags, DB_DELIMITER) ;
754 if (info->db_RE_flags & R_FIXEDLEN)
755 info->db_RE_bval = (u_char) ' ' ;
757 info->db_RE_bval = (u_char) '\n' ;
758 DB_flags(info->flags, DB_DELIMITER) ;
763 info->flags |= DB_RENUMBER ;
769 croak("type is not of type DB_File::HASHINFO, DB_File::BTREEINFO or DB_File::RECNOINFO");
773 /* OS2 Specific Code */
780 #ifdef DB_VERSION_MAJOR
786 /* Map 1.x flags to 2.x flags */
787 if ((flags & O_CREAT) == O_CREAT)
791 if ((flags & O_NONBLOCK) == O_NONBLOCK)
796 if (flags == O_RDONLY)
798 if (flags & O_RDONLY) == O_RDONLY)
803 if ((flags & O_TRUNC) == O_TRUNC)
804 Flags |= DB_TRUNCATE ;
807 status = db_open(name, RETVAL->type, Flags, mode, NULL, openinfo, &RETVAL->dbp) ;
809 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor) ;
816 RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ;
827 croak("DB_File::%s not implemented on this architecture", s);
841 if (strEQ(name, "BTREEMAGIC"))
847 if (strEQ(name, "BTREEVERSION"))
857 if (strEQ(name, "DB_LOCK"))
863 if (strEQ(name, "DB_SHMEM"))
869 if (strEQ(name, "DB_TXN"))
883 if (strEQ(name, "HASHMAGIC"))
889 if (strEQ(name, "HASHVERSION"))
905 if (strEQ(name, "MAX_PAGE_NUMBER"))
906 #ifdef MAX_PAGE_NUMBER
907 return (U32)MAX_PAGE_NUMBER;
911 if (strEQ(name, "MAX_PAGE_OFFSET"))
912 #ifdef MAX_PAGE_OFFSET
913 return MAX_PAGE_OFFSET;
917 if (strEQ(name, "MAX_REC_NUMBER"))
918 #ifdef MAX_REC_NUMBER
919 return (U32)MAX_REC_NUMBER;
933 if (strEQ(name, "RET_ERROR"))
939 if (strEQ(name, "RET_SPECIAL"))
945 if (strEQ(name, "RET_SUCCESS"))
951 if (strEQ(name, "R_CURSOR"))
957 if (strEQ(name, "R_DUP"))
963 if (strEQ(name, "R_FIRST"))
969 if (strEQ(name, "R_FIXEDLEN"))
975 if (strEQ(name, "R_IAFTER"))
981 if (strEQ(name, "R_IBEFORE"))
987 if (strEQ(name, "R_LAST"))
993 if (strEQ(name, "R_NEXT"))
999 if (strEQ(name, "R_NOKEY"))
1005 if (strEQ(name, "R_NOOVERWRITE"))
1006 #ifdef R_NOOVERWRITE
1007 return R_NOOVERWRITE;
1011 if (strEQ(name, "R_PREV"))
1017 if (strEQ(name, "R_RECNOSYNC"))
1023 if (strEQ(name, "R_SETCURSOR"))
1029 if (strEQ(name, "R_SNAPSHOT"))
1063 MODULE = DB_File PACKAGE = DB_File PREFIX = db_
1069 empty.data = &zero ;
1070 empty.size = sizeof(recno_t) ;
1081 db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_HASH)
1088 char * name = (char *) NULL ;
1089 SV * sv = (SV *) NULL ;
1091 if (items >= 3 && SvOK(ST(2)))
1092 name = (char*) SvPV(ST(2), na) ;
1097 RETVAL = ParseOpenInfo(isHASH, name, flags, mode, sv) ;
1098 if (RETVAL->dbp == NULL)
1111 SvREFCNT_dec(db->hash) ;
1113 SvREFCNT_dec(db->compare) ;
1115 SvREFCNT_dec(db->prefix) ;
1117 #ifdef DB_VERSION_MAJOR
1124 db_DELETE(db, key, flags=0)
1142 RETVAL = (((db->dbp)->get)(db->dbp, TXN &key, &value, 0) == 0) ;
1148 db_FETCH(db, key, flags=0)
1158 /* RETVAL = ((db->dbp)->get)(db->dbp, TXN &key, &value, flags) ; */
1159 RETVAL = db_get(db, key, value, flags) ;
1160 ST(0) = sv_newmortal();
1162 sv_setpvn(ST(0), value.data, value.size);
1166 db_STORE(db, key, value, flags=0)
1187 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1188 ST(0) = sv_newmortal();
1191 if (db->type != DB_RECNO)
1192 sv_setpvn(ST(0), key.data, key.size);
1194 sv_setiv(ST(0), (I32)*(I32*)key.data - 1);
1209 RETVAL = do_SEQ(db, key, value, R_NEXT) ;
1210 ST(0) = sv_newmortal();
1213 if (db->type != DB_RECNO)
1214 sv_setpvn(ST(0), key.data, key.size);
1216 sv_setiv(ST(0), (I32)*(I32*)key.data - 1);
1221 # These would be nice for RECNO
1238 #ifdef DB_VERSION_MAJOR
1239 /* get the first value */
1240 RETVAL = do_SEQ(db, key, value, DB_FIRST) ;
1245 for (i = items-1 ; i > 0 ; --i)
1247 value.data = SvPV(ST(i), na) ;
1251 key.size = sizeof(int) ;
1252 #ifdef DB_VERSION_MAJOR
1253 RETVAL = (db->cursor->c_put)(db->cursor, &key, &value, DB_BEFORE) ;
1255 RETVAL = (Db->put)(Db, &key, &value, R_IBEFORE) ;
1277 /* First get the final value */
1278 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1279 ST(0) = sv_newmortal();
1283 /* the call to del will trash value, so take a copy now */
1284 sv_setpvn(ST(0), value.data, value.size);
1285 RETVAL = db_del(db, key, R_CURSOR) ;
1287 sv_setsv(ST(0), &sv_undef);
1303 /* get the first value */
1304 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1305 ST(0) = sv_newmortal();
1309 /* the call to del will trash value, so take a copy now */
1310 sv_setpvn(ST(0), value.data, value.size);
1311 RETVAL = db_del(db, key, R_CURSOR) ;
1313 sv_setsv (ST(0), &sv_undef) ;
1324 DBTKEY * keyptr = &key ;
1332 /* Set the Cursor to the Last element */
1333 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1338 #ifdef DB_VERSION_MAJOR
1339 for (i = 1 ; i < items ; ++i)
1342 ++ (* (int*)key.data) ;
1343 value.data = SvPV(ST(i), na) ;
1345 RETVAL = (Db->put)(Db, NULL, &key, &value, 0) ;
1350 for (i = items - 1 ; i > 0 ; --i)
1352 value.data = SvPV(ST(i), na) ;
1354 RETVAL = (Db->put)(Db, keyptr, &value, R_IAFTER) ;
1370 RETVAL = GetArrayLength(db) ;
1376 # Now provide an interface to the rest of the DB functionality
1380 db_del(db, key, flags=0)
1386 RETVAL = db_del(db, key, flags) ;
1387 #ifdef DB_VERSION_MAJOR
1390 else if (RETVAL == DB_NOTFOUND)
1398 db_get(db, key, value, flags=0)
1406 RETVAL = db_get(db, key, value, flags) ;
1407 #ifdef DB_VERSION_MAJOR
1410 else if (RETVAL == DB_NOTFOUND)
1418 db_put(db, key, value, flags=0)
1425 RETVAL = db_put(db, key, value, flags) ;
1426 #ifdef DB_VERSION_MAJOR
1429 else if (RETVAL == DB_KEYEXIST)
1434 key if (flags & (R_IAFTER|R_IBEFORE)) OutputKey(ST(1), key);
1442 #ifdef DB_VERSION_MAJOR
1444 status = (db->in_memory
1446 : ((db->dbp)->fd)(db->dbp, &RETVAL) ) ;
1450 RETVAL = (db->in_memory
1452 : ((db->dbp)->fd)(db->dbp) ) ;
1458 db_sync(db, flags=0)
1463 RETVAL = db_sync(db, flags) ;
1464 #ifdef DB_VERSION_MAJOR
1473 db_seq(db, key, value, flags)
1481 RETVAL = db_seq(db, key, value, flags);
1482 #ifdef DB_VERSION_MAJOR
1485 else if (RETVAL == DB_NOTFOUND)