3 DB_File.xs -- Perl 5 interface to Berkeley DB
5 written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
6 last modified 2nd Feb 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.
66 /* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
67 * shortly #included by the <db.h>) __attribute__ to the possibly
68 * already defined __attribute__, for example by GNUC or by Perl. */
72 /* If Perl has been compiled with Threads support,the symbol op will
73 be defined here. This clashes with a field name in db.h, so get rid of it.
86 #ifdef DB_VERSION_MAJOR
88 /* map version 2 features & constants onto their version 1 equivalent */
93 #define DB_Prefix_t size_t
98 #define DB_Hash_t u_int32_t
100 /* DBTYPE stays the same */
101 /* HASHINFO, RECNOINFO and BTREEINFO map to DB_INFO */
102 typedef DB_INFO INFO ;
104 /* version 2 has db_recno_t in place of recno_t */
105 typedef db_recno_t recno_t;
108 #define R_CURSOR DB_SET_RANGE
109 #define R_FIRST DB_FIRST
110 #define R_IAFTER DB_AFTER
111 #define R_IBEFORE DB_BEFORE
112 #define R_LAST DB_LAST
113 #define R_NEXT DB_NEXT
114 #define R_NOOVERWRITE DB_NOOVERWRITE
115 #define R_PREV DB_PREV
116 #define R_SETCURSOR 0
117 #define R_RECNOSYNC 0
118 #define R_FIXEDLEN DB_FIXEDLEN
121 #define db_HA_hash h_hash
122 #define db_HA_ffactor h_ffactor
123 #define db_HA_nelem h_nelem
124 #define db_HA_bsize db_pagesize
125 #define db_HA_cachesize db_cachesize
126 #define db_HA_lorder db_lorder
128 #define db_BT_compare bt_compare
129 #define db_BT_prefix bt_prefix
130 #define db_BT_flags flags
131 #define db_BT_psize db_pagesize
132 #define db_BT_cachesize db_cachesize
133 #define db_BT_lorder db_lorder
134 #define db_BT_maxkeypage
135 #define db_BT_minkeypage
138 #define db_RE_reclen re_len
139 #define db_RE_flags flags
140 #define db_RE_bval re_pad
141 #define db_RE_bfname re_source
142 #define db_RE_psize db_pagesize
143 #define db_RE_cachesize db_cachesize
144 #define db_RE_lorder db_lorder
148 #define do_SEQ(db, key, value, flag) (db->cursor->c_get)(db->cursor, &key, &value, flag)
151 #define DBT_flags(x) x.flags = 0
152 #define DB_flags(x, v) x |= v
154 #else /* db version 1.x */
167 #define DB_Prefix_t mDB_Prefix_t
174 #define DB_Hash_t mDB_Hash_t
177 #define db_HA_hash hash.hash
178 #define db_HA_ffactor hash.ffactor
179 #define db_HA_nelem hash.nelem
180 #define db_HA_bsize hash.bsize
181 #define db_HA_cachesize hash.cachesize
182 #define db_HA_lorder hash.lorder
184 #define db_BT_compare btree.compare
185 #define db_BT_prefix btree.prefix
186 #define db_BT_flags btree.flags
187 #define db_BT_psize btree.psize
188 #define db_BT_cachesize btree.cachesize
189 #define db_BT_lorder btree.lorder
190 #define db_BT_maxkeypage btree.maxkeypage
191 #define db_BT_minkeypage btree.minkeypage
193 #define db_RE_reclen recno.reclen
194 #define db_RE_flags recno.flags
195 #define db_RE_bval recno.bval
196 #define db_RE_bfname recno.bfname
197 #define db_RE_psize recno.psize
198 #define db_RE_cachesize recno.cachesize
199 #define db_RE_lorder recno.lorder
203 #define do_SEQ(db, key, value, flag) (db->dbp->seq)(db->dbp, &key, &value, flag)
205 #define DB_flags(x, v)
207 #endif /* db version 1 */
211 #define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, TXN &key, flags)
212 #define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, flags)
213 #define db_FETCH(db, key, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
215 #define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags)
216 #define db_get(db, key, value, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
217 #ifdef DB_VERSION_MAJOR
218 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp, 0)
219 #define db_close(db) ((db->dbp)->close)(db->dbp, 0)
220 #define db_del(db, key, flags) ((flags & R_CURSOR) \
221 ? ((db->cursor)->c_del)(db->cursor, 0) \
222 : ((db->dbp)->del)(db->dbp, NULL, &key, flags) )
226 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp)
227 #define db_close(db) ((db->dbp)->close)(db->dbp)
228 #define db_del(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags)
229 #define db_put(db, key, value, flags) ((db->dbp)->put)(db->dbp, &key, &value, flags)
233 #define db_seq(db, key, value, flags) do_SEQ(db, key, value, flags)
243 #ifdef DB_VERSION_MAJOR
248 typedef DB_File_type * DB_File ;
251 #define my_sv_setpvn(sv, d, s) sv_setpvn(sv, (s ? d : (void*)""), s)
253 #define OutputValue(arg, name) \
254 { if (RETVAL == 0) { \
255 my_sv_setpvn(arg, name.data, name.size) ; \
259 #define OutputKey(arg, name) \
262 if (db->type != DB_RECNO) { \
263 my_sv_setpvn(arg, name.data, name.size); \
266 sv_setiv(arg, (I32)*(I32*)name.data - 1); \
271 /* Internal Global Data */
272 static recno_t Value ;
273 static recno_t zero = 0 ;
274 static DB_File CurrentDB ;
275 static DBTKEY empty ;
277 #ifdef DB_VERSION_MAJOR
280 db_put(db, key, value, flags)
289 if (flags & R_CURSOR) {
290 status = ((db->cursor)->c_del)(db->cursor, 0);
297 return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;
301 #endif /* DB_VERSION_MAJOR */
306 SV * ver_sv = perl_get_sv("DB_File::db_version", TRUE) ;
307 #ifdef DB_VERSION_MAJOR
308 int Major, Minor, Patch ;
310 (void)db_version(&Major, &Minor, &Patch) ;
312 /* check that libdb is recent enough */
313 if (Major == 2 && Minor == 0 && Patch < 5)
314 croak("DB_File needs Berkeley DB 2.0.5 or greater, you have %d.%d.%d\n",
315 Major, Minor, Patch) ;
318 sv_setpvf(ver_sv, "%d.%d", Major, Minor) ;
322 sprintf(buffer, "%d.%d", Major, Minor) ;
323 sv_setpv(ver_sv, buffer) ;
328 sv_setiv(ver_sv, 1) ;
335 btree_compare(key1, key2)
340 void * data1, * data2 ;
347 /* As newSVpv will assume that the data pointer is a null terminated C
348 string if the size parameter is 0, make sure that data points to an
349 empty string if the length is 0
361 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
362 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
365 count = perl_call_sv(CurrentDB->compare, G_SCALAR);
370 croak ("DB_File btree_compare: expected 1 return value from compare sub, got %d\n", count) ;
382 btree_prefix(key1, key2)
387 void * data1, * data2 ;
394 /* As newSVpv will assume that the data pointer is a null terminated C
395 string if the size parameter is 0, make sure that data points to an
396 empty string if the length is 0
408 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
409 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
412 count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
417 croak ("DB_File btree_prefix: expected 1 return value from prefix sub, got %d\n", count) ;
440 /* DGH - Next two lines added to fix corrupted stack problem */
446 XPUSHs(sv_2mortal(newSVpv((char*)data,size)));
449 count = perl_call_sv(CurrentDB->hash, G_SCALAR);
454 croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ;
472 printf ("HASH Info\n") ;
473 printf (" hash = %s\n",
474 (hash->db_HA_hash != NULL ? "redefined" : "default")) ;
475 printf (" bsize = %d\n", hash->db_HA_bsize) ;
476 printf (" ffactor = %d\n", hash->db_HA_ffactor) ;
477 printf (" nelem = %d\n", hash->db_HA_nelem) ;
478 printf (" cachesize = %d\n", hash->db_HA_cachesize) ;
479 printf (" lorder = %d\n", hash->db_HA_lorder) ;
487 printf ("RECNO Info\n") ;
488 printf (" flags = %d\n", recno->db_RE_flags) ;
489 printf (" cachesize = %d\n", recno->db_RE_cachesize) ;
490 printf (" psize = %d\n", recno->db_RE_psize) ;
491 printf (" lorder = %d\n", recno->db_RE_lorder) ;
492 printf (" reclen = %ul\n", (unsigned long)recno->db_RE_reclen) ;
493 printf (" bval = %d 0x%x\n", recno->db_RE_bval, recno->db_RE_bval) ;
494 printf (" bfname = %d [%s]\n", recno->db_RE_bfname, recno->db_RE_bfname) ;
501 printf ("BTREE Info\n") ;
502 printf (" compare = %s\n",
503 (btree->db_BT_compare ? "redefined" : "default")) ;
504 printf (" prefix = %s\n",
505 (btree->db_BT_prefix ? "redefined" : "default")) ;
506 printf (" flags = %d\n", btree->db_BT_flags) ;
507 printf (" cachesize = %d\n", btree->db_BT_cachesize) ;
508 printf (" psize = %d\n", btree->db_BT_psize) ;
509 #ifndef DB_VERSION_MAJOR
510 printf (" maxkeypage = %d\n", btree->db_BT_maxkeypage) ;
511 printf (" minkeypage = %d\n", btree->db_BT_minkeypage) ;
513 printf (" lorder = %d\n", btree->db_BT_lorder) ;
518 #define PrintRecno(recno)
519 #define PrintHash(hash)
520 #define PrintBtree(btree)
535 RETVAL = do_SEQ(db, key, value, R_LAST) ;
537 RETVAL = *(I32 *)key.data ;
538 else /* No key means empty file */
541 return ((I32)RETVAL) ;
545 GetRecnoKey(db, value)
550 /* Get the length of the array */
551 I32 length = GetArrayLength(db) ;
553 /* check for attempt to write before start of array */
554 if (length + value + 1 <= 0)
555 croak("Modification of non-creatable array value attempted, subscript %ld", (long)value) ;
557 value = length + value + 1 ;
566 ParseOpenInfo(isHASH, name, flags, mode, sv)
575 DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ;
576 void * openinfo = NULL ;
577 INFO * info = &RETVAL->info ;
579 /* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
580 Zero(RETVAL, 1, DB_File_type) ;
582 /* Default to HASH */
583 RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
584 RETVAL->type = DB_HASH ;
586 /* DGH - Next line added to avoid SEGV on existing hash DB */
589 /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */
590 RETVAL->in_memory = (name == NULL) ;
595 croak ("type parameter is not a reference") ;
597 svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ;
598 if (svp && SvOK(*svp))
599 action = (HV*) SvRV(*svp) ;
601 croak("internal error") ;
603 if (sv_isa(sv, "DB_File::HASHINFO"))
607 croak("DB_File can only tie an associative array to a DB_HASH database") ;
609 RETVAL->type = DB_HASH ;
610 openinfo = (void*)info ;
612 svp = hv_fetch(action, "hash", 4, FALSE);
614 if (svp && SvOK(*svp))
616 info->db_HA_hash = hash_cb ;
617 RETVAL->hash = newSVsv(*svp) ;
620 info->db_HA_hash = NULL ;
622 svp = hv_fetch(action, "ffactor", 7, FALSE);
623 info->db_HA_ffactor = svp ? SvIV(*svp) : 0;
625 svp = hv_fetch(action, "nelem", 5, FALSE);
626 info->db_HA_nelem = svp ? SvIV(*svp) : 0;
628 svp = hv_fetch(action, "bsize", 5, FALSE);
629 info->db_HA_bsize = svp ? SvIV(*svp) : 0;
631 svp = hv_fetch(action, "cachesize", 9, FALSE);
632 info->db_HA_cachesize = svp ? SvIV(*svp) : 0;
634 svp = hv_fetch(action, "lorder", 6, FALSE);
635 info->db_HA_lorder = svp ? SvIV(*svp) : 0;
639 else if (sv_isa(sv, "DB_File::BTREEINFO"))
642 croak("DB_File can only tie an associative array to a DB_BTREE database");
644 RETVAL->type = DB_BTREE ;
645 openinfo = (void*)info ;
647 svp = hv_fetch(action, "compare", 7, FALSE);
648 if (svp && SvOK(*svp))
650 info->db_BT_compare = btree_compare ;
651 RETVAL->compare = newSVsv(*svp) ;
654 info->db_BT_compare = NULL ;
656 svp = hv_fetch(action, "prefix", 6, FALSE);
657 if (svp && SvOK(*svp))
659 info->db_BT_prefix = btree_prefix ;
660 RETVAL->prefix = newSVsv(*svp) ;
663 info->db_BT_prefix = NULL ;
665 svp = hv_fetch(action, "flags", 5, FALSE);
666 info->db_BT_flags = svp ? SvIV(*svp) : 0;
668 svp = hv_fetch(action, "cachesize", 9, FALSE);
669 info->db_BT_cachesize = svp ? SvIV(*svp) : 0;
671 #ifndef DB_VERSION_MAJOR
672 svp = hv_fetch(action, "minkeypage", 10, FALSE);
673 info->btree.minkeypage = svp ? SvIV(*svp) : 0;
675 svp = hv_fetch(action, "maxkeypage", 10, FALSE);
676 info->btree.maxkeypage = svp ? SvIV(*svp) : 0;
679 svp = hv_fetch(action, "psize", 5, FALSE);
680 info->db_BT_psize = svp ? SvIV(*svp) : 0;
682 svp = hv_fetch(action, "lorder", 6, FALSE);
683 info->db_BT_lorder = svp ? SvIV(*svp) : 0;
688 else if (sv_isa(sv, "DB_File::RECNOINFO"))
691 croak("DB_File can only tie an array to a DB_RECNO database");
693 RETVAL->type = DB_RECNO ;
694 openinfo = (void *)info ;
696 info->db_RE_flags = 0 ;
698 svp = hv_fetch(action, "flags", 5, FALSE);
699 info->db_RE_flags = (u_long) (svp ? SvIV(*svp) : 0);
701 svp = hv_fetch(action, "reclen", 6, FALSE);
702 info->db_RE_reclen = (size_t) (svp ? SvIV(*svp) : 0);
704 svp = hv_fetch(action, "cachesize", 9, FALSE);
705 info->db_RE_cachesize = (u_int) (svp ? SvIV(*svp) : 0);
707 svp = hv_fetch(action, "psize", 5, FALSE);
708 info->db_RE_psize = (u_int) (svp ? SvIV(*svp) : 0);
710 svp = hv_fetch(action, "lorder", 6, FALSE);
711 info->db_RE_lorder = (int) (svp ? SvIV(*svp) : 0);
713 #ifdef DB_VERSION_MAJOR
714 info->re_source = name ;
717 svp = hv_fetch(action, "bfname", 6, FALSE);
718 if (svp && SvOK(*svp)) {
719 char * ptr = SvPV(*svp,na) ;
720 #ifdef DB_VERSION_MAJOR
721 name = (char*) na ? ptr : NULL ;
723 info->db_RE_bfname = (char*) (na ? ptr : NULL) ;
727 #ifdef DB_VERSION_MAJOR
730 info->db_RE_bfname = NULL ;
733 svp = hv_fetch(action, "bval", 4, FALSE);
734 #ifdef DB_VERSION_MAJOR
735 if (svp && SvOK(*svp))
739 value = (int)*SvPV(*svp, na) ;
743 if (info->flags & DB_FIXEDLEN) {
744 info->re_pad = value ;
745 info->flags |= DB_PAD ;
748 info->re_delim = value ;
749 info->flags |= DB_DELIMITER ;
754 if (svp && SvOK(*svp))
757 info->db_RE_bval = (u_char)*SvPV(*svp, na) ;
759 info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ;
760 DB_flags(info->flags, DB_DELIMITER) ;
765 if (info->db_RE_flags & R_FIXEDLEN)
766 info->db_RE_bval = (u_char) ' ' ;
768 info->db_RE_bval = (u_char) '\n' ;
769 DB_flags(info->flags, DB_DELIMITER) ;
774 info->flags |= DB_RENUMBER ;
780 croak("type is not of type DB_File::HASHINFO, DB_File::BTREEINFO or DB_File::RECNOINFO");
784 /* OS2 Specific Code */
791 #ifdef DB_VERSION_MAJOR
797 /* Map 1.x flags to 2.x flags */
798 if ((flags & O_CREAT) == O_CREAT)
802 if ((flags & O_NONBLOCK) == O_NONBLOCK)
807 if (flags == O_RDONLY)
809 if (flags & O_RDONLY) == O_RDONLY)
814 if ((flags & O_TRUNC) == O_TRUNC)
815 Flags |= DB_TRUNCATE ;
818 status = db_open(name, RETVAL->type, Flags, mode, NULL, openinfo, &RETVAL->dbp) ;
820 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor) ;
827 RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ;
838 croak("DB_File::%s not implemented on this architecture", s);
852 if (strEQ(name, "BTREEMAGIC"))
858 if (strEQ(name, "BTREEVERSION"))
868 if (strEQ(name, "DB_LOCK"))
874 if (strEQ(name, "DB_SHMEM"))
880 if (strEQ(name, "DB_TXN"))
894 if (strEQ(name, "HASHMAGIC"))
900 if (strEQ(name, "HASHVERSION"))
916 if (strEQ(name, "MAX_PAGE_NUMBER"))
917 #ifdef MAX_PAGE_NUMBER
918 return (U32)MAX_PAGE_NUMBER;
922 if (strEQ(name, "MAX_PAGE_OFFSET"))
923 #ifdef MAX_PAGE_OFFSET
924 return MAX_PAGE_OFFSET;
928 if (strEQ(name, "MAX_REC_NUMBER"))
929 #ifdef MAX_REC_NUMBER
930 return (U32)MAX_REC_NUMBER;
944 if (strEQ(name, "RET_ERROR"))
950 if (strEQ(name, "RET_SPECIAL"))
956 if (strEQ(name, "RET_SUCCESS"))
962 if (strEQ(name, "R_CURSOR"))
968 if (strEQ(name, "R_DUP"))
974 if (strEQ(name, "R_FIRST"))
980 if (strEQ(name, "R_FIXEDLEN"))
986 if (strEQ(name, "R_IAFTER"))
992 if (strEQ(name, "R_IBEFORE"))
998 if (strEQ(name, "R_LAST"))
1004 if (strEQ(name, "R_NEXT"))
1010 if (strEQ(name, "R_NOKEY"))
1016 if (strEQ(name, "R_NOOVERWRITE"))
1017 #ifdef R_NOOVERWRITE
1018 return R_NOOVERWRITE;
1022 if (strEQ(name, "R_PREV"))
1028 if (strEQ(name, "R_RECNOSYNC"))
1034 if (strEQ(name, "R_SETCURSOR"))
1040 if (strEQ(name, "R_SNAPSHOT"))
1074 MODULE = DB_File PACKAGE = DB_File PREFIX = db_
1080 empty.data = &zero ;
1081 empty.size = sizeof(recno_t) ;
1092 db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_HASH)
1099 char * name = (char *) NULL ;
1100 SV * sv = (SV *) NULL ;
1102 if (items >= 3 && SvOK(ST(2)))
1103 name = (char*) SvPV(ST(2), na) ;
1108 RETVAL = ParseOpenInfo(isHASH, name, flags, mode, sv) ;
1109 if (RETVAL->dbp == NULL)
1122 SvREFCNT_dec(db->hash) ;
1124 SvREFCNT_dec(db->compare) ;
1126 SvREFCNT_dec(db->prefix) ;
1128 #ifdef DB_VERSION_MAJOR
1135 db_DELETE(db, key, flags=0)
1153 RETVAL = (((db->dbp)->get)(db->dbp, TXN &key, &value, 0) == 0) ;
1159 db_FETCH(db, key, flags=0)
1169 /* RETVAL = ((db->dbp)->get)(db->dbp, TXN &key, &value, flags) ; */
1170 RETVAL = db_get(db, key, value, flags) ;
1171 ST(0) = sv_newmortal();
1173 my_sv_setpvn(ST(0), value.data, value.size);
1177 db_STORE(db, key, value, flags=0)
1198 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1199 ST(0) = sv_newmortal();
1202 if (db->type != DB_RECNO)
1203 my_sv_setpvn(ST(0), key.data, key.size);
1205 sv_setiv(ST(0), (I32)*(I32*)key.data - 1);
1220 RETVAL = do_SEQ(db, key, value, R_NEXT) ;
1221 ST(0) = sv_newmortal();
1224 if (db->type != DB_RECNO)
1225 my_sv_setpvn(ST(0), key.data, key.size);
1227 sv_setiv(ST(0), (I32)*(I32*)key.data - 1);
1232 # These would be nice for RECNO
1250 #ifdef DB_VERSION_MAJOR
1251 /* get the first value */
1252 RETVAL = do_SEQ(db, key, value, DB_FIRST) ;
1257 for (i = items-1 ; i > 0 ; --i)
1259 value.data = SvPV(ST(i), na) ;
1263 key.size = sizeof(int) ;
1264 #ifdef DB_VERSION_MAJOR
1265 RETVAL = (db->cursor->c_put)(db->cursor, &key, &value, DB_BEFORE) ;
1267 RETVAL = (Db->put)(Db, &key, &value, R_IBEFORE) ;
1290 /* First get the final value */
1291 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1292 ST(0) = sv_newmortal();
1296 /* the call to del will trash value, so take a copy now */
1297 my_sv_setpvn(ST(0), value.data, value.size);
1298 RETVAL = db_del(db, key, R_CURSOR) ;
1300 sv_setsv(ST(0), &sv_undef);
1317 /* get the first value */
1318 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1319 ST(0) = sv_newmortal();
1323 /* the call to del will trash value, so take a copy now */
1324 my_sv_setpvn(ST(0), value.data, value.size);
1325 RETVAL = db_del(db, key, R_CURSOR) ;
1327 sv_setsv (ST(0), &sv_undef) ;
1339 DBTKEY * keyptr = &key ;
1347 /* Set the Cursor to the Last element */
1348 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1353 #ifdef DB_VERSION_MAJOR
1354 for (i = 1 ; i < items ; ++i)
1357 ++ (* (int*)key.data) ;
1358 value.data = SvPV(ST(i), na) ;
1360 RETVAL = (Db->put)(Db, NULL, &key, &value, 0) ;
1365 for (i = items - 1 ; i > 0 ; --i)
1367 value.data = SvPV(ST(i), na) ;
1369 RETVAL = (Db->put)(Db, keyptr, &value, R_IAFTER) ;
1383 ALIAS: FETCHSIZE = 1
1386 RETVAL = GetArrayLength(db) ;
1392 # Now provide an interface to the rest of the DB functionality
1396 db_del(db, key, flags=0)
1402 RETVAL = db_del(db, key, flags) ;
1403 #ifdef DB_VERSION_MAJOR
1406 else if (RETVAL == DB_NOTFOUND)
1414 db_get(db, key, value, flags=0)
1422 RETVAL = db_get(db, key, value, flags) ;
1423 #ifdef DB_VERSION_MAJOR
1426 else if (RETVAL == DB_NOTFOUND)
1434 db_put(db, key, value, flags=0)
1441 RETVAL = db_put(db, key, value, flags) ;
1442 #ifdef DB_VERSION_MAJOR
1445 else if (RETVAL == DB_KEYEXIST)
1450 key if (flags & (R_IAFTER|R_IBEFORE)) OutputKey(ST(1), key);
1458 #ifdef DB_VERSION_MAJOR
1460 status = (db->in_memory
1462 : ((db->dbp)->fd)(db->dbp, &RETVAL) ) ;
1466 RETVAL = (db->in_memory
1468 : ((db->dbp)->fd)(db->dbp) ) ;
1474 db_sync(db, flags=0)
1479 RETVAL = db_sync(db, flags) ;
1480 #ifdef DB_VERSION_MAJOR
1489 db_seq(db, key, value, flags)
1497 RETVAL = db_seq(db, key, value, flags);
1498 #ifdef DB_VERSION_MAJOR
1501 else if (RETVAL == DB_NOTFOUND)