3 DB_File.xs -- Perl 5 interface to Berkeley DB
5 written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
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.
70 /* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
71 * shortly #included by the <db.h>) __attribute__ to the possibly
72 * already defined __attribute__, for example by GNUC or by Perl. */
76 /* If Perl has been compiled with Threads support,the symbol op will
77 be defined here. This clashes with a field name in db.h, so get rid of it.
90 #ifdef DB_VERSION_MAJOR
92 /* map version 2 features & constants onto their version 1 equivalent */
97 #define DB_Prefix_t size_t
102 #define DB_Hash_t u_int32_t
104 /* DBTYPE stays the same */
105 /* HASHINFO, RECNOINFO and BTREEINFO map to DB_INFO */
106 typedef DB_INFO INFO ;
108 /* version 2 has db_recno_t in place of recno_t */
109 typedef db_recno_t recno_t;
112 #define R_CURSOR DB_SET_RANGE
113 #define R_FIRST DB_FIRST
114 #define R_IAFTER DB_AFTER
115 #define R_IBEFORE DB_BEFORE
116 #define R_LAST DB_LAST
117 #define R_NEXT DB_NEXT
118 #define R_NOOVERWRITE DB_NOOVERWRITE
119 #define R_PREV DB_PREV
120 #define R_SETCURSOR 0
121 #define R_RECNOSYNC 0
122 #define R_FIXEDLEN DB_FIXEDLEN
125 #define db_HA_hash h_hash
126 #define db_HA_ffactor h_ffactor
127 #define db_HA_nelem h_nelem
128 #define db_HA_bsize db_pagesize
129 #define db_HA_cachesize db_cachesize
130 #define db_HA_lorder db_lorder
132 #define db_BT_compare bt_compare
133 #define db_BT_prefix bt_prefix
134 #define db_BT_flags flags
135 #define db_BT_psize db_pagesize
136 #define db_BT_cachesize db_cachesize
137 #define db_BT_lorder db_lorder
138 #define db_BT_maxkeypage
139 #define db_BT_minkeypage
142 #define db_RE_reclen re_len
143 #define db_RE_flags flags
144 #define db_RE_bval re_pad
145 #define db_RE_bfname re_source
146 #define db_RE_psize db_pagesize
147 #define db_RE_cachesize db_cachesize
148 #define db_RE_lorder db_lorder
152 #define do_SEQ(db, key, value, flag) (db->cursor->c_get)(db->cursor, &key, &value, flag)
155 #define DBT_flags(x) x.flags = 0
156 #define DB_flags(x, v) x |= v
158 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
159 #define flagSet(flags, bitmask) ((flags) & (bitmask))
161 #define flagSet(flags, bitmask) (((flags) & DB_OPFLAGS_MASK) == (bitmask))
164 #else /* db version 1.x */
177 #define DB_Prefix_t mDB_Prefix_t
184 #define DB_Hash_t mDB_Hash_t
187 #define db_HA_hash hash.hash
188 #define db_HA_ffactor hash.ffactor
189 #define db_HA_nelem hash.nelem
190 #define db_HA_bsize hash.bsize
191 #define db_HA_cachesize hash.cachesize
192 #define db_HA_lorder hash.lorder
194 #define db_BT_compare btree.compare
195 #define db_BT_prefix btree.prefix
196 #define db_BT_flags btree.flags
197 #define db_BT_psize btree.psize
198 #define db_BT_cachesize btree.cachesize
199 #define db_BT_lorder btree.lorder
200 #define db_BT_maxkeypage btree.maxkeypage
201 #define db_BT_minkeypage btree.minkeypage
203 #define db_RE_reclen recno.reclen
204 #define db_RE_flags recno.flags
205 #define db_RE_bval recno.bval
206 #define db_RE_bfname recno.bfname
207 #define db_RE_psize recno.psize
208 #define db_RE_cachesize recno.cachesize
209 #define db_RE_lorder recno.lorder
213 #define do_SEQ(db, key, value, flag) (db->dbp->seq)(db->dbp, &key, &value, flag)
215 #define DB_flags(x, v)
216 #define flagSet(flags, bitmask) ((flags) & (bitmask))
218 #endif /* db version 1 */
222 #define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, TXN &key, flags)
223 #define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, flags)
224 #define db_FETCH(db, key, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
226 #define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags)
227 #define db_get(db, key, value, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
229 #ifdef DB_VERSION_MAJOR
230 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp, 0)
231 #define db_close(db) ((db->dbp)->close)(db->dbp, 0)
232 #define db_del(db, key, flags) (flagSet(flags, R_CURSOR) \
233 ? ((db->cursor)->c_del)(db->cursor, 0) \
234 : ((db->dbp)->del)(db->dbp, NULL, &key, flags) )
238 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp)
239 #define db_close(db) ((db->dbp)->close)(db->dbp)
240 #define db_del(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags)
241 #define db_put(db, key, value, flags) ((db->dbp)->put)(db->dbp, &key, &value, flags)
246 #define db_seq(db, key, value, flags) do_SEQ(db, key, value, flags)
256 #ifdef DB_VERSION_MAJOR
261 typedef DB_File_type * DB_File ;
264 #define my_sv_setpvn(sv, d, s) sv_setpvn(sv, (s ? d : (void*)""), s)
266 #define OutputValue(arg, name) \
267 { if (RETVAL == 0) { \
268 my_sv_setpvn(arg, name.data, name.size) ; \
272 #define OutputKey(arg, name) \
275 if (db->type != DB_RECNO) { \
276 my_sv_setpvn(arg, name.data, name.size); \
279 sv_setiv(arg, (I32)*(I32*)name.data - 1); \
284 /* Internal Global Data */
285 static recno_t Value ;
286 static recno_t zero = 0 ;
287 static DB_File CurrentDB ;
288 static DBTKEY empty ;
290 #ifdef DB_VERSION_MAJOR
293 db_put(db, key, value, flags)
302 if (flagSet(flags, R_CURSOR)) {
303 status = ((db->cursor)->c_del)(db->cursor, 0);
307 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
310 flags &= ~DB_OPFLAGS_MASK ;
315 return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;
319 #endif /* DB_VERSION_MAJOR */
324 SV * ver_sv = perl_get_sv("DB_File::db_version", TRUE) ;
325 #ifdef DB_VERSION_MAJOR
326 int Major, Minor, Patch ;
328 (void)db_version(&Major, &Minor, &Patch) ;
330 /* check that libdb is recent enough */
331 if (Major == 2 && Minor == 0 && Patch < 5)
332 croak("DB_File needs Berkeley DB 2.0.5 or greater, you have %d.%d.%d\n",
333 Major, Minor, Patch) ;
336 sv_setpvf(ver_sv, "%d.%d", Major, Minor) ;
340 sprintf(buffer, "%d.%d", Major, Minor) ;
341 sv_setpv(ver_sv, buffer) ;
346 sv_setiv(ver_sv, 1) ;
353 btree_compare(key1, key2)
358 void * data1, * data2 ;
365 /* As newSVpv will assume that the data pointer is a null terminated C
366 string if the size parameter is 0, make sure that data points to an
367 empty string if the length is 0
379 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
380 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
383 count = perl_call_sv(CurrentDB->compare, G_SCALAR);
388 croak ("DB_File btree_compare: expected 1 return value from compare sub, got %d\n", count) ;
400 btree_prefix(key1, key2)
405 void * data1, * data2 ;
412 /* As newSVpv will assume that the data pointer is a null terminated C
413 string if the size parameter is 0, make sure that data points to an
414 empty string if the length is 0
426 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
427 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
430 count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
435 croak ("DB_File btree_prefix: expected 1 return value from prefix sub, got %d\n", count) ;
458 /* DGH - Next two lines added to fix corrupted stack problem */
464 XPUSHs(sv_2mortal(newSVpv((char*)data,size)));
467 count = perl_call_sv(CurrentDB->hash, G_SCALAR);
472 croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ;
490 printf ("HASH Info\n") ;
491 printf (" hash = %s\n",
492 (hash->db_HA_hash != NULL ? "redefined" : "default")) ;
493 printf (" bsize = %d\n", hash->db_HA_bsize) ;
494 printf (" ffactor = %d\n", hash->db_HA_ffactor) ;
495 printf (" nelem = %d\n", hash->db_HA_nelem) ;
496 printf (" cachesize = %d\n", hash->db_HA_cachesize) ;
497 printf (" lorder = %d\n", hash->db_HA_lorder) ;
505 printf ("RECNO Info\n") ;
506 printf (" flags = %d\n", recno->db_RE_flags) ;
507 printf (" cachesize = %d\n", recno->db_RE_cachesize) ;
508 printf (" psize = %d\n", recno->db_RE_psize) ;
509 printf (" lorder = %d\n", recno->db_RE_lorder) ;
510 printf (" reclen = %ul\n", (unsigned long)recno->db_RE_reclen) ;
511 printf (" bval = %d 0x%x\n", recno->db_RE_bval, recno->db_RE_bval) ;
512 printf (" bfname = %d [%s]\n", recno->db_RE_bfname, recno->db_RE_bfname) ;
519 printf ("BTREE Info\n") ;
520 printf (" compare = %s\n",
521 (btree->db_BT_compare ? "redefined" : "default")) ;
522 printf (" prefix = %s\n",
523 (btree->db_BT_prefix ? "redefined" : "default")) ;
524 printf (" flags = %d\n", btree->db_BT_flags) ;
525 printf (" cachesize = %d\n", btree->db_BT_cachesize) ;
526 printf (" psize = %d\n", btree->db_BT_psize) ;
527 #ifndef DB_VERSION_MAJOR
528 printf (" maxkeypage = %d\n", btree->db_BT_maxkeypage) ;
529 printf (" minkeypage = %d\n", btree->db_BT_minkeypage) ;
531 printf (" lorder = %d\n", btree->db_BT_lorder) ;
536 #define PrintRecno(recno)
537 #define PrintHash(hash)
538 #define PrintBtree(btree)
553 RETVAL = do_SEQ(db, key, value, R_LAST) ;
555 RETVAL = *(I32 *)key.data ;
556 else /* No key means empty file */
559 return ((I32)RETVAL) ;
563 GetRecnoKey(db, value)
568 /* Get the length of the array */
569 I32 length = GetArrayLength(db) ;
571 /* check for attempt to write before start of array */
572 if (length + value + 1 <= 0)
573 croak("Modification of non-creatable array value attempted, subscript %ld", (long)value) ;
575 value = length + value + 1 ;
584 ParseOpenInfo(isHASH, name, flags, mode, sv)
593 DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ;
594 void * openinfo = NULL ;
595 INFO * info = &RETVAL->info ;
597 /* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
598 Zero(RETVAL, 1, DB_File_type) ;
600 /* Default to HASH */
601 RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
602 RETVAL->type = DB_HASH ;
604 /* DGH - Next line added to avoid SEGV on existing hash DB */
607 /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */
608 RETVAL->in_memory = (name == NULL) ;
613 croak ("type parameter is not a reference") ;
615 svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ;
616 if (svp && SvOK(*svp))
617 action = (HV*) SvRV(*svp) ;
619 croak("internal error") ;
621 if (sv_isa(sv, "DB_File::HASHINFO"))
625 croak("DB_File can only tie an associative array to a DB_HASH database") ;
627 RETVAL->type = DB_HASH ;
628 openinfo = (void*)info ;
630 svp = hv_fetch(action, "hash", 4, FALSE);
632 if (svp && SvOK(*svp))
634 info->db_HA_hash = hash_cb ;
635 RETVAL->hash = newSVsv(*svp) ;
638 info->db_HA_hash = NULL ;
640 svp = hv_fetch(action, "ffactor", 7, FALSE);
641 info->db_HA_ffactor = svp ? SvIV(*svp) : 0;
643 svp = hv_fetch(action, "nelem", 5, FALSE);
644 info->db_HA_nelem = svp ? SvIV(*svp) : 0;
646 svp = hv_fetch(action, "bsize", 5, FALSE);
647 info->db_HA_bsize = svp ? SvIV(*svp) : 0;
649 svp = hv_fetch(action, "cachesize", 9, FALSE);
650 info->db_HA_cachesize = svp ? SvIV(*svp) : 0;
652 svp = hv_fetch(action, "lorder", 6, FALSE);
653 info->db_HA_lorder = svp ? SvIV(*svp) : 0;
657 else if (sv_isa(sv, "DB_File::BTREEINFO"))
660 croak("DB_File can only tie an associative array to a DB_BTREE database");
662 RETVAL->type = DB_BTREE ;
663 openinfo = (void*)info ;
665 svp = hv_fetch(action, "compare", 7, FALSE);
666 if (svp && SvOK(*svp))
668 info->db_BT_compare = btree_compare ;
669 RETVAL->compare = newSVsv(*svp) ;
672 info->db_BT_compare = NULL ;
674 svp = hv_fetch(action, "prefix", 6, FALSE);
675 if (svp && SvOK(*svp))
677 info->db_BT_prefix = btree_prefix ;
678 RETVAL->prefix = newSVsv(*svp) ;
681 info->db_BT_prefix = NULL ;
683 svp = hv_fetch(action, "flags", 5, FALSE);
684 info->db_BT_flags = svp ? SvIV(*svp) : 0;
686 svp = hv_fetch(action, "cachesize", 9, FALSE);
687 info->db_BT_cachesize = svp ? SvIV(*svp) : 0;
689 #ifndef DB_VERSION_MAJOR
690 svp = hv_fetch(action, "minkeypage", 10, FALSE);
691 info->btree.minkeypage = svp ? SvIV(*svp) : 0;
693 svp = hv_fetch(action, "maxkeypage", 10, FALSE);
694 info->btree.maxkeypage = svp ? SvIV(*svp) : 0;
697 svp = hv_fetch(action, "psize", 5, FALSE);
698 info->db_BT_psize = svp ? SvIV(*svp) : 0;
700 svp = hv_fetch(action, "lorder", 6, FALSE);
701 info->db_BT_lorder = svp ? SvIV(*svp) : 0;
706 else if (sv_isa(sv, "DB_File::RECNOINFO"))
709 croak("DB_File can only tie an array to a DB_RECNO database");
711 RETVAL->type = DB_RECNO ;
712 openinfo = (void *)info ;
714 info->db_RE_flags = 0 ;
716 svp = hv_fetch(action, "flags", 5, FALSE);
717 info->db_RE_flags = (u_long) (svp ? SvIV(*svp) : 0);
719 svp = hv_fetch(action, "reclen", 6, FALSE);
720 info->db_RE_reclen = (size_t) (svp ? SvIV(*svp) : 0);
722 svp = hv_fetch(action, "cachesize", 9, FALSE);
723 info->db_RE_cachesize = (u_int) (svp ? SvIV(*svp) : 0);
725 svp = hv_fetch(action, "psize", 5, FALSE);
726 info->db_RE_psize = (u_int) (svp ? SvIV(*svp) : 0);
728 svp = hv_fetch(action, "lorder", 6, FALSE);
729 info->db_RE_lorder = (int) (svp ? SvIV(*svp) : 0);
731 #ifdef DB_VERSION_MAJOR
732 info->re_source = name ;
735 svp = hv_fetch(action, "bfname", 6, FALSE);
736 if (svp && SvOK(*svp)) {
737 char * ptr = SvPV(*svp,PL_na) ;
738 #ifdef DB_VERSION_MAJOR
739 name = (char*) PL_na ? ptr : NULL ;
741 info->db_RE_bfname = (char*) (PL_na ? ptr : NULL) ;
745 #ifdef DB_VERSION_MAJOR
748 info->db_RE_bfname = NULL ;
751 svp = hv_fetch(action, "bval", 4, FALSE);
752 #ifdef DB_VERSION_MAJOR
753 if (svp && SvOK(*svp))
757 value = (int)*SvPV(*svp, PL_na) ;
761 if (info->flags & DB_FIXEDLEN) {
762 info->re_pad = value ;
763 info->flags |= DB_PAD ;
766 info->re_delim = value ;
767 info->flags |= DB_DELIMITER ;
772 if (svp && SvOK(*svp))
775 info->db_RE_bval = (u_char)*SvPV(*svp, PL_na) ;
777 info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ;
778 DB_flags(info->flags, DB_DELIMITER) ;
783 if (info->db_RE_flags & R_FIXEDLEN)
784 info->db_RE_bval = (u_char) ' ' ;
786 info->db_RE_bval = (u_char) '\n' ;
787 DB_flags(info->flags, DB_DELIMITER) ;
792 info->flags |= DB_RENUMBER ;
798 croak("type is not of type DB_File::HASHINFO, DB_File::BTREEINFO or DB_File::RECNOINFO");
802 /* OS2 Specific Code */
809 #ifdef DB_VERSION_MAJOR
815 /* Map 1.x flags to 2.x flags */
816 if ((flags & O_CREAT) == O_CREAT)
820 if ((flags & O_NONBLOCK) == O_NONBLOCK)
825 if (flags == O_RDONLY)
827 if ((flags & O_RDONLY) == O_RDONLY)
832 if ((flags & O_TRUNC) == O_TRUNC)
833 Flags |= DB_TRUNCATE ;
836 status = db_open(name, RETVAL->type, Flags, mode, NULL, openinfo, &RETVAL->dbp) ;
838 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor) ;
845 RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ;
856 croak("DB_File::%s not implemented on this architecture", s);
870 if (strEQ(name, "BTREEMAGIC"))
876 if (strEQ(name, "BTREEVERSION"))
886 if (strEQ(name, "DB_LOCK"))
892 if (strEQ(name, "DB_SHMEM"))
898 if (strEQ(name, "DB_TXN"))
912 if (strEQ(name, "HASHMAGIC"))
918 if (strEQ(name, "HASHVERSION"))
934 if (strEQ(name, "MAX_PAGE_NUMBER"))
935 #ifdef MAX_PAGE_NUMBER
936 return (U32)MAX_PAGE_NUMBER;
940 if (strEQ(name, "MAX_PAGE_OFFSET"))
941 #ifdef MAX_PAGE_OFFSET
942 return MAX_PAGE_OFFSET;
946 if (strEQ(name, "MAX_REC_NUMBER"))
947 #ifdef MAX_REC_NUMBER
948 return (U32)MAX_REC_NUMBER;
962 if (strEQ(name, "RET_ERROR"))
968 if (strEQ(name, "RET_SPECIAL"))
974 if (strEQ(name, "RET_SUCCESS"))
980 if (strEQ(name, "R_CURSOR"))
986 if (strEQ(name, "R_DUP"))
992 if (strEQ(name, "R_FIRST"))
998 if (strEQ(name, "R_FIXEDLEN"))
1004 if (strEQ(name, "R_IAFTER"))
1010 if (strEQ(name, "R_IBEFORE"))
1016 if (strEQ(name, "R_LAST"))
1022 if (strEQ(name, "R_NEXT"))
1028 if (strEQ(name, "R_NOKEY"))
1034 if (strEQ(name, "R_NOOVERWRITE"))
1035 #ifdef R_NOOVERWRITE
1036 return R_NOOVERWRITE;
1040 if (strEQ(name, "R_PREV"))
1046 if (strEQ(name, "R_RECNOSYNC"))
1052 if (strEQ(name, "R_SETCURSOR"))
1058 if (strEQ(name, "R_SNAPSHOT"))
1092 MODULE = DB_File PACKAGE = DB_File PREFIX = db_
1098 empty.data = &zero ;
1099 empty.size = sizeof(recno_t) ;
1110 db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_HASH)
1117 char * name = (char *) NULL ;
1118 SV * sv = (SV *) NULL ;
1120 if (items >= 3 && SvOK(ST(2)))
1121 name = (char*) SvPV(ST(2), PL_na) ;
1126 RETVAL = ParseOpenInfo(isHASH, name, flags, mode, sv) ;
1127 if (RETVAL->dbp == NULL)
1140 SvREFCNT_dec(db->hash) ;
1142 SvREFCNT_dec(db->compare) ;
1144 SvREFCNT_dec(db->prefix) ;
1146 #ifdef DB_VERSION_MAJOR
1153 db_DELETE(db, key, flags=0)
1171 RETVAL = (((db->dbp)->get)(db->dbp, TXN &key, &value, 0) == 0) ;
1177 db_FETCH(db, key, flags=0)
1187 /* RETVAL = ((db->dbp)->get)(db->dbp, TXN &key, &value, flags) ; */
1188 RETVAL = db_get(db, key, value, flags) ;
1189 ST(0) = sv_newmortal();
1190 OutputValue(ST(0), value)
1194 db_STORE(db, key, value, flags=0)
1215 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1216 ST(0) = sv_newmortal();
1217 OutputKey(ST(0), key) ;
1231 RETVAL = do_SEQ(db, key, value, R_NEXT) ;
1232 ST(0) = sv_newmortal();
1233 OutputKey(ST(0), key) ;
1237 # These would be nice for RECNO
1255 #ifdef DB_VERSION_MAJOR
1256 /* get the first value */
1257 RETVAL = do_SEQ(db, key, value, DB_FIRST) ;
1262 for (i = items-1 ; i > 0 ; --i)
1264 value.data = SvPV(ST(i), PL_na) ;
1265 value.size = PL_na ;
1268 key.size = sizeof(int) ;
1269 #ifdef DB_VERSION_MAJOR
1270 RETVAL = (db->cursor->c_put)(db->cursor, &key, &value, DB_BEFORE) ;
1272 RETVAL = (Db->put)(Db, &key, &value, R_IBEFORE) ;
1295 /* First get the final value */
1296 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1297 ST(0) = sv_newmortal();
1301 /* the call to del will trash value, so take a copy now */
1302 OutputValue(ST(0), value) ;
1303 RETVAL = db_del(db, key, R_CURSOR) ;
1305 sv_setsv(ST(0), &PL_sv_undef);
1322 /* get the first value */
1323 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1324 ST(0) = sv_newmortal();
1328 /* the call to del will trash value, so take a copy now */
1329 OutputValue(ST(0), value) ;
1330 RETVAL = db_del(db, key, R_CURSOR) ;
1332 sv_setsv (ST(0), &PL_sv_undef) ;
1344 DBTKEY * keyptr = &key ;
1352 /* Set the Cursor to the Last element */
1353 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1358 #ifdef DB_VERSION_MAJOR
1359 for (i = 1 ; i < items ; ++i)
1362 ++ (* (int*)key.data) ;
1363 value.data = SvPV(ST(i), PL_na) ;
1364 value.size = PL_na ;
1365 RETVAL = (Db->put)(Db, NULL, &key, &value, 0) ;
1370 for (i = items - 1 ; i > 0 ; --i)
1372 value.data = SvPV(ST(i), PL_na) ;
1373 value.size = PL_na ;
1374 RETVAL = (Db->put)(Db, keyptr, &value, R_IAFTER) ;
1388 ALIAS: FETCHSIZE = 1
1391 RETVAL = GetArrayLength(db) ;
1397 # Now provide an interface to the rest of the DB functionality
1401 db_del(db, key, flags=0)
1407 RETVAL = db_del(db, key, flags) ;
1408 #ifdef DB_VERSION_MAJOR
1411 else if (RETVAL == DB_NOTFOUND)
1419 db_get(db, key, value, flags=0)
1427 RETVAL = db_get(db, key, value, flags) ;
1428 #ifdef DB_VERSION_MAJOR
1431 else if (RETVAL == DB_NOTFOUND)
1439 db_put(db, key, value, flags=0)
1446 RETVAL = db_put(db, key, value, flags) ;
1447 #ifdef DB_VERSION_MAJOR
1450 else if (RETVAL == DB_KEYEXIST)
1455 key if (flagSet(flags, R_IAFTER) || flagSet(flags, R_IBEFORE)) OutputKey(ST(1), key);
1463 #ifdef DB_VERSION_MAJOR
1465 status = (db->in_memory
1467 : ((db->dbp)->fd)(db->dbp, &RETVAL) ) ;
1471 RETVAL = (db->in_memory
1473 : ((db->dbp)->fd)(db->dbp) ) ;
1479 db_sync(db, flags=0)
1484 RETVAL = db_sync(db, flags) ;
1485 #ifdef DB_VERSION_MAJOR
1494 db_seq(db, key, value, flags)
1502 RETVAL = db_seq(db, key, value, flags);
1503 #ifdef DB_VERSION_MAJOR
1506 else if (RETVAL == DB_NOTFOUND)