3 DB_File.xs -- Perl 5 interface to Berkeley DB
5 written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
6 last modified 16th May 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
68 /* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
69 * shortly #included by the <db.h>) __attribute__ to the possibly
70 * already defined __attribute__, for example by GNUC or by Perl. */
74 /* If Perl has been compiled with Threads support,the symbol op will
75 be defined here. This clashes with a field name in db.h, so get rid of it.
88 #ifdef DB_VERSION_MAJOR
90 /* map version 2 features & constants onto their version 1 equivalent */
95 #define DB_Prefix_t size_t
100 #define DB_Hash_t u_int32_t
102 /* DBTYPE stays the same */
103 /* HASHINFO, RECNOINFO and BTREEINFO map to DB_INFO */
104 typedef DB_INFO INFO ;
106 /* version 2 has db_recno_t in place of recno_t */
107 typedef db_recno_t recno_t;
110 #define R_CURSOR DB_SET_RANGE
111 #define R_FIRST DB_FIRST
112 #define R_IAFTER DB_AFTER
113 #define R_IBEFORE DB_BEFORE
114 #define R_LAST DB_LAST
115 #define R_NEXT DB_NEXT
116 #define R_NOOVERWRITE DB_NOOVERWRITE
117 #define R_PREV DB_PREV
118 #define R_SETCURSOR 0
119 #define R_RECNOSYNC 0
120 #define R_FIXEDLEN DB_FIXEDLEN
123 #define db_HA_hash h_hash
124 #define db_HA_ffactor h_ffactor
125 #define db_HA_nelem h_nelem
126 #define db_HA_bsize db_pagesize
127 #define db_HA_cachesize db_cachesize
128 #define db_HA_lorder db_lorder
130 #define db_BT_compare bt_compare
131 #define db_BT_prefix bt_prefix
132 #define db_BT_flags flags
133 #define db_BT_psize db_pagesize
134 #define db_BT_cachesize db_cachesize
135 #define db_BT_lorder db_lorder
136 #define db_BT_maxkeypage
137 #define db_BT_minkeypage
140 #define db_RE_reclen re_len
141 #define db_RE_flags flags
142 #define db_RE_bval re_pad
143 #define db_RE_bfname re_source
144 #define db_RE_psize db_pagesize
145 #define db_RE_cachesize db_cachesize
146 #define db_RE_lorder db_lorder
150 #define do_SEQ(db, key, value, flag) (db->cursor->c_get)(db->cursor, &key, &value, flag)
153 #define DBT_flags(x) x.flags = 0
154 #define DB_flags(x, v) x |= v
156 #else /* db version 1.x */
169 #define DB_Prefix_t mDB_Prefix_t
176 #define DB_Hash_t mDB_Hash_t
179 #define db_HA_hash hash.hash
180 #define db_HA_ffactor hash.ffactor
181 #define db_HA_nelem hash.nelem
182 #define db_HA_bsize hash.bsize
183 #define db_HA_cachesize hash.cachesize
184 #define db_HA_lorder hash.lorder
186 #define db_BT_compare btree.compare
187 #define db_BT_prefix btree.prefix
188 #define db_BT_flags btree.flags
189 #define db_BT_psize btree.psize
190 #define db_BT_cachesize btree.cachesize
191 #define db_BT_lorder btree.lorder
192 #define db_BT_maxkeypage btree.maxkeypage
193 #define db_BT_minkeypage btree.minkeypage
195 #define db_RE_reclen recno.reclen
196 #define db_RE_flags recno.flags
197 #define db_RE_bval recno.bval
198 #define db_RE_bfname recno.bfname
199 #define db_RE_psize recno.psize
200 #define db_RE_cachesize recno.cachesize
201 #define db_RE_lorder recno.lorder
205 #define do_SEQ(db, key, value, flag) (db->dbp->seq)(db->dbp, &key, &value, flag)
207 #define DB_flags(x, v)
209 #endif /* db version 1 */
213 #define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, TXN &key, flags)
214 #define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, flags)
215 #define db_FETCH(db, key, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
217 #define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags)
218 #define db_get(db, key, value, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
219 #ifdef DB_VERSION_MAJOR
220 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp, 0)
221 #define db_close(db) ((db->dbp)->close)(db->dbp, 0)
222 #define db_del(db, key, flags) ((flags & R_CURSOR) \
223 ? ((db->cursor)->c_del)(db->cursor, 0) \
224 : ((db->dbp)->del)(db->dbp, NULL, &key, flags) )
228 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp)
229 #define db_close(db) ((db->dbp)->close)(db->dbp)
230 #define db_del(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags)
231 #define db_put(db, key, value, flags) ((db->dbp)->put)(db->dbp, &key, &value, flags)
235 #define db_seq(db, key, value, flags) do_SEQ(db, key, value, flags)
245 #ifdef DB_VERSION_MAJOR
250 typedef DB_File_type * DB_File ;
253 #define my_sv_setpvn(sv, d, s) sv_setpvn(sv, (s ? d : (void*)""), s)
255 #define OutputValue(arg, name) \
256 { if (RETVAL == 0) { \
257 my_sv_setpvn(arg, name.data, name.size) ; \
261 #define OutputKey(arg, name) \
264 if (db->type != DB_RECNO) { \
265 my_sv_setpvn(arg, name.data, name.size); \
268 sv_setiv(arg, (I32)*(I32*)name.data - 1); \
273 /* Internal Global Data */
274 static recno_t Value ;
275 static recno_t zero = 0 ;
276 static DB_File CurrentDB ;
277 static DBTKEY empty ;
279 #ifdef DB_VERSION_MAJOR
282 db_put(db, key, value, flags)
291 if (flags & R_CURSOR) {
292 status = ((db->cursor)->c_del)(db->cursor, 0);
299 return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;
303 #endif /* DB_VERSION_MAJOR */
308 SV * ver_sv = perl_get_sv("DB_File::db_version", TRUE) ;
309 #ifdef DB_VERSION_MAJOR
310 int Major, Minor, Patch ;
312 (void)db_version(&Major, &Minor, &Patch) ;
314 /* check that libdb is recent enough */
315 if (Major == 2 && Minor == 0 && Patch < 5)
316 croak("DB_File needs Berkeley DB 2.0.5 or greater, you have %d.%d.%d\n",
317 Major, Minor, Patch) ;
320 sv_setpvf(ver_sv, "%d.%d", Major, Minor) ;
324 sprintf(buffer, "%d.%d", Major, Minor) ;
325 sv_setpv(ver_sv, buffer) ;
330 sv_setiv(ver_sv, 1) ;
337 btree_compare(key1, key2)
342 void * data1, * data2 ;
349 /* As newSVpv will assume that the data pointer is a null terminated C
350 string if the size parameter is 0, make sure that data points to an
351 empty string if the length is 0
363 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
364 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
367 count = perl_call_sv(CurrentDB->compare, G_SCALAR);
372 croak ("DB_File btree_compare: expected 1 return value from compare sub, got %d\n", count) ;
384 btree_prefix(key1, key2)
389 void * data1, * data2 ;
396 /* As newSVpv will assume that the data pointer is a null terminated C
397 string if the size parameter is 0, make sure that data points to an
398 empty string if the length is 0
410 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
411 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
414 count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
419 croak ("DB_File btree_prefix: expected 1 return value from prefix sub, got %d\n", count) ;
442 /* DGH - Next two lines added to fix corrupted stack problem */
448 XPUSHs(sv_2mortal(newSVpv((char*)data,size)));
451 count = perl_call_sv(CurrentDB->hash, G_SCALAR);
456 croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ;
474 printf ("HASH Info\n") ;
475 printf (" hash = %s\n",
476 (hash->db_HA_hash != NULL ? "redefined" : "default")) ;
477 printf (" bsize = %d\n", hash->db_HA_bsize) ;
478 printf (" ffactor = %d\n", hash->db_HA_ffactor) ;
479 printf (" nelem = %d\n", hash->db_HA_nelem) ;
480 printf (" cachesize = %d\n", hash->db_HA_cachesize) ;
481 printf (" lorder = %d\n", hash->db_HA_lorder) ;
489 printf ("RECNO Info\n") ;
490 printf (" flags = %d\n", recno->db_RE_flags) ;
491 printf (" cachesize = %d\n", recno->db_RE_cachesize) ;
492 printf (" psize = %d\n", recno->db_RE_psize) ;
493 printf (" lorder = %d\n", recno->db_RE_lorder) ;
494 printf (" reclen = %ul\n", (unsigned long)recno->db_RE_reclen) ;
495 printf (" bval = %d 0x%x\n", recno->db_RE_bval, recno->db_RE_bval) ;
496 printf (" bfname = %d [%s]\n", recno->db_RE_bfname, recno->db_RE_bfname) ;
503 printf ("BTREE Info\n") ;
504 printf (" compare = %s\n",
505 (btree->db_BT_compare ? "redefined" : "default")) ;
506 printf (" prefix = %s\n",
507 (btree->db_BT_prefix ? "redefined" : "default")) ;
508 printf (" flags = %d\n", btree->db_BT_flags) ;
509 printf (" cachesize = %d\n", btree->db_BT_cachesize) ;
510 printf (" psize = %d\n", btree->db_BT_psize) ;
511 #ifndef DB_VERSION_MAJOR
512 printf (" maxkeypage = %d\n", btree->db_BT_maxkeypage) ;
513 printf (" minkeypage = %d\n", btree->db_BT_minkeypage) ;
515 printf (" lorder = %d\n", btree->db_BT_lorder) ;
520 #define PrintRecno(recno)
521 #define PrintHash(hash)
522 #define PrintBtree(btree)
537 RETVAL = do_SEQ(db, key, value, R_LAST) ;
539 RETVAL = *(I32 *)key.data ;
540 else /* No key means empty file */
543 return ((I32)RETVAL) ;
547 GetRecnoKey(db, value)
552 /* Get the length of the array */
553 I32 length = GetArrayLength(db) ;
555 /* check for attempt to write before start of array */
556 if (length + value + 1 <= 0)
557 croak("Modification of non-creatable array value attempted, subscript %ld", (long)value) ;
559 value = length + value + 1 ;
568 ParseOpenInfo(isHASH, name, flags, mode, sv)
577 DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ;
578 void * openinfo = NULL ;
579 INFO * info = &RETVAL->info ;
581 /* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
582 Zero(RETVAL, 1, DB_File_type) ;
584 /* Default to HASH */
585 RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
586 RETVAL->type = DB_HASH ;
588 /* DGH - Next line added to avoid SEGV on existing hash DB */
591 /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */
592 RETVAL->in_memory = (name == NULL) ;
597 croak ("type parameter is not a reference") ;
599 svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ;
600 if (svp && SvOK(*svp))
601 action = (HV*) SvRV(*svp) ;
603 croak("internal error") ;
605 if (sv_isa(sv, "DB_File::HASHINFO"))
609 croak("DB_File can only tie an associative array to a DB_HASH database") ;
611 RETVAL->type = DB_HASH ;
612 openinfo = (void*)info ;
614 svp = hv_fetch(action, "hash", 4, FALSE);
616 if (svp && SvOK(*svp))
618 info->db_HA_hash = hash_cb ;
619 RETVAL->hash = newSVsv(*svp) ;
622 info->db_HA_hash = NULL ;
624 svp = hv_fetch(action, "ffactor", 7, FALSE);
625 info->db_HA_ffactor = svp ? SvIV(*svp) : 0;
627 svp = hv_fetch(action, "nelem", 5, FALSE);
628 info->db_HA_nelem = svp ? SvIV(*svp) : 0;
630 svp = hv_fetch(action, "bsize", 5, FALSE);
631 info->db_HA_bsize = svp ? SvIV(*svp) : 0;
633 svp = hv_fetch(action, "cachesize", 9, FALSE);
634 info->db_HA_cachesize = svp ? SvIV(*svp) : 0;
636 svp = hv_fetch(action, "lorder", 6, FALSE);
637 info->db_HA_lorder = svp ? SvIV(*svp) : 0;
641 else if (sv_isa(sv, "DB_File::BTREEINFO"))
644 croak("DB_File can only tie an associative array to a DB_BTREE database");
646 RETVAL->type = DB_BTREE ;
647 openinfo = (void*)info ;
649 svp = hv_fetch(action, "compare", 7, FALSE);
650 if (svp && SvOK(*svp))
652 info->db_BT_compare = btree_compare ;
653 RETVAL->compare = newSVsv(*svp) ;
656 info->db_BT_compare = NULL ;
658 svp = hv_fetch(action, "prefix", 6, FALSE);
659 if (svp && SvOK(*svp))
661 info->db_BT_prefix = btree_prefix ;
662 RETVAL->prefix = newSVsv(*svp) ;
665 info->db_BT_prefix = NULL ;
667 svp = hv_fetch(action, "flags", 5, FALSE);
668 info->db_BT_flags = svp ? SvIV(*svp) : 0;
670 svp = hv_fetch(action, "cachesize", 9, FALSE);
671 info->db_BT_cachesize = svp ? SvIV(*svp) : 0;
673 #ifndef DB_VERSION_MAJOR
674 svp = hv_fetch(action, "minkeypage", 10, FALSE);
675 info->btree.minkeypage = svp ? SvIV(*svp) : 0;
677 svp = hv_fetch(action, "maxkeypage", 10, FALSE);
678 info->btree.maxkeypage = svp ? SvIV(*svp) : 0;
681 svp = hv_fetch(action, "psize", 5, FALSE);
682 info->db_BT_psize = svp ? SvIV(*svp) : 0;
684 svp = hv_fetch(action, "lorder", 6, FALSE);
685 info->db_BT_lorder = svp ? SvIV(*svp) : 0;
690 else if (sv_isa(sv, "DB_File::RECNOINFO"))
693 croak("DB_File can only tie an array to a DB_RECNO database");
695 RETVAL->type = DB_RECNO ;
696 openinfo = (void *)info ;
698 info->db_RE_flags = 0 ;
700 svp = hv_fetch(action, "flags", 5, FALSE);
701 info->db_RE_flags = (u_long) (svp ? SvIV(*svp) : 0);
703 svp = hv_fetch(action, "reclen", 6, FALSE);
704 info->db_RE_reclen = (size_t) (svp ? SvIV(*svp) : 0);
706 svp = hv_fetch(action, "cachesize", 9, FALSE);
707 info->db_RE_cachesize = (u_int) (svp ? SvIV(*svp) : 0);
709 svp = hv_fetch(action, "psize", 5, FALSE);
710 info->db_RE_psize = (u_int) (svp ? SvIV(*svp) : 0);
712 svp = hv_fetch(action, "lorder", 6, FALSE);
713 info->db_RE_lorder = (int) (svp ? SvIV(*svp) : 0);
715 #ifdef DB_VERSION_MAJOR
716 info->re_source = name ;
719 svp = hv_fetch(action, "bfname", 6, FALSE);
720 if (svp && SvOK(*svp)) {
721 char * ptr = SvPV(*svp,PL_na) ;
722 #ifdef DB_VERSION_MAJOR
723 name = (char*) PL_na ? ptr : NULL ;
725 info->db_RE_bfname = (char*) (PL_na ? ptr : NULL) ;
729 #ifdef DB_VERSION_MAJOR
732 info->db_RE_bfname = NULL ;
735 svp = hv_fetch(action, "bval", 4, FALSE);
736 #ifdef DB_VERSION_MAJOR
737 if (svp && SvOK(*svp))
741 value = (int)*SvPV(*svp, PL_na) ;
745 if (info->flags & DB_FIXEDLEN) {
746 info->re_pad = value ;
747 info->flags |= DB_PAD ;
750 info->re_delim = value ;
751 info->flags |= DB_DELIMITER ;
756 if (svp && SvOK(*svp))
759 info->db_RE_bval = (u_char)*SvPV(*svp, PL_na) ;
761 info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ;
762 DB_flags(info->flags, DB_DELIMITER) ;
767 if (info->db_RE_flags & R_FIXEDLEN)
768 info->db_RE_bval = (u_char) ' ' ;
770 info->db_RE_bval = (u_char) '\n' ;
771 DB_flags(info->flags, DB_DELIMITER) ;
776 info->flags |= DB_RENUMBER ;
782 croak("type is not of type DB_File::HASHINFO, DB_File::BTREEINFO or DB_File::RECNOINFO");
786 /* OS2 Specific Code */
793 #ifdef DB_VERSION_MAJOR
799 /* Map 1.x flags to 2.x flags */
800 if ((flags & O_CREAT) == O_CREAT)
804 if ((flags & O_NONBLOCK) == O_NONBLOCK)
809 if (flags == O_RDONLY)
811 if (flags & O_RDONLY) == O_RDONLY)
816 if ((flags & O_TRUNC) == O_TRUNC)
817 Flags |= DB_TRUNCATE ;
820 status = db_open(name, RETVAL->type, Flags, mode, NULL, openinfo, &RETVAL->dbp) ;
822 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor) ;
829 RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ;
840 croak("DB_File::%s not implemented on this architecture", s);
854 if (strEQ(name, "BTREEMAGIC"))
860 if (strEQ(name, "BTREEVERSION"))
870 if (strEQ(name, "DB_LOCK"))
876 if (strEQ(name, "DB_SHMEM"))
882 if (strEQ(name, "DB_TXN"))
896 if (strEQ(name, "HASHMAGIC"))
902 if (strEQ(name, "HASHVERSION"))
918 if (strEQ(name, "MAX_PAGE_NUMBER"))
919 #ifdef MAX_PAGE_NUMBER
920 return (U32)MAX_PAGE_NUMBER;
924 if (strEQ(name, "MAX_PAGE_OFFSET"))
925 #ifdef MAX_PAGE_OFFSET
926 return MAX_PAGE_OFFSET;
930 if (strEQ(name, "MAX_REC_NUMBER"))
931 #ifdef MAX_REC_NUMBER
932 return (U32)MAX_REC_NUMBER;
946 if (strEQ(name, "RET_ERROR"))
952 if (strEQ(name, "RET_SPECIAL"))
958 if (strEQ(name, "RET_SUCCESS"))
964 if (strEQ(name, "R_CURSOR"))
970 if (strEQ(name, "R_DUP"))
976 if (strEQ(name, "R_FIRST"))
982 if (strEQ(name, "R_FIXEDLEN"))
988 if (strEQ(name, "R_IAFTER"))
994 if (strEQ(name, "R_IBEFORE"))
1000 if (strEQ(name, "R_LAST"))
1006 if (strEQ(name, "R_NEXT"))
1012 if (strEQ(name, "R_NOKEY"))
1018 if (strEQ(name, "R_NOOVERWRITE"))
1019 #ifdef R_NOOVERWRITE
1020 return R_NOOVERWRITE;
1024 if (strEQ(name, "R_PREV"))
1030 if (strEQ(name, "R_RECNOSYNC"))
1036 if (strEQ(name, "R_SETCURSOR"))
1042 if (strEQ(name, "R_SNAPSHOT"))
1076 MODULE = DB_File PACKAGE = DB_File PREFIX = db_
1082 empty.data = &zero ;
1083 empty.size = sizeof(recno_t) ;
1094 db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_HASH)
1101 char * name = (char *) NULL ;
1102 SV * sv = (SV *) NULL ;
1104 if (items >= 3 && SvOK(ST(2)))
1105 name = (char*) SvPV(ST(2), PL_na) ;
1110 RETVAL = ParseOpenInfo(isHASH, name, flags, mode, sv) ;
1111 if (RETVAL->dbp == NULL)
1124 SvREFCNT_dec(db->hash) ;
1126 SvREFCNT_dec(db->compare) ;
1128 SvREFCNT_dec(db->prefix) ;
1130 #ifdef DB_VERSION_MAJOR
1137 db_DELETE(db, key, flags=0)
1155 RETVAL = (((db->dbp)->get)(db->dbp, TXN &key, &value, 0) == 0) ;
1161 db_FETCH(db, key, flags=0)
1171 /* RETVAL = ((db->dbp)->get)(db->dbp, TXN &key, &value, flags) ; */
1172 RETVAL = db_get(db, key, value, flags) ;
1173 ST(0) = sv_newmortal();
1174 OutputValue(ST(0), value)
1178 db_STORE(db, key, value, flags=0)
1199 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1200 ST(0) = sv_newmortal();
1201 OutputKey(ST(0), key) ;
1215 RETVAL = do_SEQ(db, key, value, R_NEXT) ;
1216 ST(0) = sv_newmortal();
1217 OutputKey(ST(0), key) ;
1221 # These would be nice for RECNO
1239 #ifdef DB_VERSION_MAJOR
1240 /* get the first value */
1241 RETVAL = do_SEQ(db, key, value, DB_FIRST) ;
1246 for (i = items-1 ; i > 0 ; --i)
1248 value.data = SvPV(ST(i), PL_na) ;
1249 value.size = PL_na ;
1252 key.size = sizeof(int) ;
1253 #ifdef DB_VERSION_MAJOR
1254 RETVAL = (db->cursor->c_put)(db->cursor, &key, &value, DB_BEFORE) ;
1256 RETVAL = (Db->put)(Db, &key, &value, R_IBEFORE) ;
1279 /* First get the final value */
1280 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1281 ST(0) = sv_newmortal();
1285 /* the call to del will trash value, so take a copy now */
1286 OutputValue(ST(0), value) ;
1287 RETVAL = db_del(db, key, R_CURSOR) ;
1289 sv_setsv(ST(0), &PL_sv_undef);
1306 /* get the first value */
1307 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
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) ;
1328 DBTKEY * keyptr = &key ;
1336 /* Set the Cursor to the Last element */
1337 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1342 #ifdef DB_VERSION_MAJOR
1343 for (i = 1 ; i < items ; ++i)
1346 ++ (* (int*)key.data) ;
1347 value.data = SvPV(ST(i), PL_na) ;
1348 value.size = PL_na ;
1349 RETVAL = (Db->put)(Db, NULL, &key, &value, 0) ;
1354 for (i = items - 1 ; i > 0 ; --i)
1356 value.data = SvPV(ST(i), PL_na) ;
1357 value.size = PL_na ;
1358 RETVAL = (Db->put)(Db, keyptr, &value, R_IAFTER) ;
1372 ALIAS: FETCHSIZE = 1
1375 RETVAL = GetArrayLength(db) ;
1381 # Now provide an interface to the rest of the DB functionality
1385 db_del(db, key, flags=0)
1391 RETVAL = db_del(db, key, flags) ;
1392 #ifdef DB_VERSION_MAJOR
1395 else if (RETVAL == DB_NOTFOUND)
1403 db_get(db, key, value, flags=0)
1411 RETVAL = db_get(db, key, value, flags) ;
1412 #ifdef DB_VERSION_MAJOR
1415 else if (RETVAL == DB_NOTFOUND)
1423 db_put(db, key, value, flags=0)
1430 RETVAL = db_put(db, key, value, flags) ;
1431 #ifdef DB_VERSION_MAJOR
1434 else if (RETVAL == DB_KEYEXIST)
1439 key if (flags & (R_IAFTER|R_IBEFORE)) OutputKey(ST(1), key);
1447 #ifdef DB_VERSION_MAJOR
1449 status = (db->in_memory
1451 : ((db->dbp)->fd)(db->dbp, &RETVAL) ) ;
1455 RETVAL = (db->in_memory
1457 : ((db->dbp)->fd)(db->dbp) ) ;
1463 db_sync(db, flags=0)
1468 RETVAL = db_sync(db, flags) ;
1469 #ifdef DB_VERSION_MAJOR
1478 db_seq(db, key, value, flags)
1486 RETVAL = db_seq(db, key, value, flags);
1487 #ifdef DB_VERSION_MAJOR
1490 else if (RETVAL == DB_NOTFOUND)