3 DB_File.xs -- Perl 5 interface to Berkeley DB
5 written by Paul Marquess <Paul.Marquess@btinternet.com>
6 last modified 21st February 1999
9 All comments/suggestions/problems are welcome
11 Copyright (c) 1995-9 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.
63 1.64 - Tidied up the 1.x to 2.x flags mapping code.
64 Added a patch from Mark Kettenis <kettenis@wins.uva.nl>
65 to fix a flag mapping problem with O_RDONLY on the Hurd
76 #include "patchlevel.h"
77 #define PERL_REVISION 5
78 #define PERL_VERSION PATCHLEVEL
79 #define PERL_SUBVERSION SUBVERSION
82 #if PERL_REVISION == 5 && (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION <= 75 ))
84 # define PL_sv_undef sv_undef
89 /* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
90 * shortly #included by the <db.h>) __attribute__ to the possibly
91 * already defined __attribute__, for example by GNUC or by Perl. */
95 /* If Perl has been compiled with Threads support,the symbol op will
96 be defined here. This clashes with a field name in db.h, so get rid of it.
109 #ifdef DB_VERSION_MAJOR
111 /* map version 2 features & constants onto their version 1 equivalent */
116 #define DB_Prefix_t size_t
121 #define DB_Hash_t u_int32_t
123 /* DBTYPE stays the same */
124 /* HASHINFO, RECNOINFO and BTREEINFO map to DB_INFO */
125 typedef DB_INFO INFO ;
127 /* version 2 has db_recno_t in place of recno_t */
128 typedef db_recno_t recno_t;
131 #define R_CURSOR DB_SET_RANGE
132 #define R_FIRST DB_FIRST
133 #define R_IAFTER DB_AFTER
134 #define R_IBEFORE DB_BEFORE
135 #define R_LAST DB_LAST
136 #define R_NEXT DB_NEXT
137 #define R_NOOVERWRITE DB_NOOVERWRITE
138 #define R_PREV DB_PREV
139 #define R_SETCURSOR 0
140 #define R_RECNOSYNC 0
141 #define R_FIXEDLEN DB_FIXEDLEN
144 #define db_HA_hash h_hash
145 #define db_HA_ffactor h_ffactor
146 #define db_HA_nelem h_nelem
147 #define db_HA_bsize db_pagesize
148 #define db_HA_cachesize db_cachesize
149 #define db_HA_lorder db_lorder
151 #define db_BT_compare bt_compare
152 #define db_BT_prefix bt_prefix
153 #define db_BT_flags flags
154 #define db_BT_psize db_pagesize
155 #define db_BT_cachesize db_cachesize
156 #define db_BT_lorder db_lorder
157 #define db_BT_maxkeypage
158 #define db_BT_minkeypage
161 #define db_RE_reclen re_len
162 #define db_RE_flags flags
163 #define db_RE_bval re_pad
164 #define db_RE_bfname re_source
165 #define db_RE_psize db_pagesize
166 #define db_RE_cachesize db_cachesize
167 #define db_RE_lorder db_lorder
171 #define do_SEQ(db, key, value, flag) (db->cursor->c_get)(db->cursor, &key, &value, flag)
174 #define DBT_flags(x) x.flags = 0
175 #define DB_flags(x, v) x |= v
177 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
178 #define flagSet(flags, bitmask) ((flags) & (bitmask))
180 #define flagSet(flags, bitmask) (((flags) & DB_OPFLAGS_MASK) == (bitmask))
183 #else /* db version 1.x */
196 #define DB_Prefix_t mDB_Prefix_t
203 #define DB_Hash_t mDB_Hash_t
206 #define db_HA_hash hash.hash
207 #define db_HA_ffactor hash.ffactor
208 #define db_HA_nelem hash.nelem
209 #define db_HA_bsize hash.bsize
210 #define db_HA_cachesize hash.cachesize
211 #define db_HA_lorder hash.lorder
213 #define db_BT_compare btree.compare
214 #define db_BT_prefix btree.prefix
215 #define db_BT_flags btree.flags
216 #define db_BT_psize btree.psize
217 #define db_BT_cachesize btree.cachesize
218 #define db_BT_lorder btree.lorder
219 #define db_BT_maxkeypage btree.maxkeypage
220 #define db_BT_minkeypage btree.minkeypage
222 #define db_RE_reclen recno.reclen
223 #define db_RE_flags recno.flags
224 #define db_RE_bval recno.bval
225 #define db_RE_bfname recno.bfname
226 #define db_RE_psize recno.psize
227 #define db_RE_cachesize recno.cachesize
228 #define db_RE_lorder recno.lorder
232 #define do_SEQ(db, key, value, flag) (db->dbp->seq)(db->dbp, &key, &value, flag)
234 #define DB_flags(x, v)
235 #define flagSet(flags, bitmask) ((flags) & (bitmask))
237 #endif /* db version 1 */
241 #define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, TXN &key, flags)
242 #define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, flags)
243 #define db_FETCH(db, key, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
245 #define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags)
246 #define db_get(db, key, value, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
248 #ifdef DB_VERSION_MAJOR
249 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp, 0)
250 #define db_close(db) ((db->dbp)->close)(db->dbp, 0)
251 #define db_del(db, key, flags) (flagSet(flags, R_CURSOR) \
252 ? ((db->cursor)->c_del)(db->cursor, 0) \
253 : ((db->dbp)->del)(db->dbp, NULL, &key, flags) )
257 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp)
258 #define db_close(db) ((db->dbp)->close)(db->dbp)
259 #define db_del(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags)
260 #define db_put(db, key, value, flags) ((db->dbp)->put)(db->dbp, &key, &value, flags)
265 #define db_seq(db, key, value, flags) do_SEQ(db, key, value, flags)
275 #ifdef DB_VERSION_MAJOR
280 typedef DB_File_type * DB_File ;
283 #define my_sv_setpvn(sv, d, s) sv_setpvn(sv, (s ? d : (void*)""), s)
285 #define OutputValue(arg, name) \
286 { if (RETVAL == 0) { \
287 my_sv_setpvn(arg, name.data, name.size) ; \
291 #define OutputKey(arg, name) \
294 if (db->type != DB_RECNO) { \
295 my_sv_setpvn(arg, name.data, name.size); \
298 sv_setiv(arg, (I32)*(I32*)name.data - 1); \
303 /* Internal Global Data */
304 static recno_t Value ;
305 static recno_t zero = 0 ;
306 static DB_File CurrentDB ;
307 static DBTKEY empty ;
309 #ifdef DB_VERSION_MAJOR
312 db_put(db, key, value, flags)
321 if (flagSet(flags, R_CURSOR)) {
322 status = ((db->cursor)->c_del)(db->cursor, 0);
326 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
329 flags &= ~DB_OPFLAGS_MASK ;
334 return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;
338 #endif /* DB_VERSION_MAJOR */
343 SV * ver_sv = perl_get_sv("DB_File::db_version", TRUE) ;
344 #ifdef DB_VERSION_MAJOR
345 int Major, Minor, Patch ;
347 (void)db_version(&Major, &Minor, &Patch) ;
349 /* check that libdb is recent enough */
350 if (Major == 2 && Minor == 0 && Patch < 5)
351 croak("DB_File needs Berkeley DB 2.0.5 or greater, you have %d.%d.%d\n",
352 Major, Minor, Patch) ;
355 sv_setpvf(ver_sv, "%d.%d", Major, Minor) ;
359 sprintf(buffer, "%d.%d", Major, Minor) ;
360 sv_setpv(ver_sv, buffer) ;
365 sv_setiv(ver_sv, 1) ;
372 btree_compare(key1, key2)
377 void * data1, * data2 ;
384 /* As newSVpv will assume that the data pointer is a null terminated C
385 string if the size parameter is 0, make sure that data points to an
386 empty string if the length is 0
398 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
399 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
402 count = perl_call_sv(CurrentDB->compare, G_SCALAR);
407 croak ("DB_File btree_compare: expected 1 return value from compare sub, got %d\n", count) ;
419 btree_prefix(key1, key2)
424 void * data1, * data2 ;
431 /* As newSVpv will assume that the data pointer is a null terminated C
432 string if the size parameter is 0, make sure that data points to an
433 empty string if the length is 0
445 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
446 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
449 count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
454 croak ("DB_File btree_prefix: expected 1 return value from prefix sub, got %d\n", count) ;
477 /* DGH - Next two lines added to fix corrupted stack problem */
483 XPUSHs(sv_2mortal(newSVpv((char*)data,size)));
486 count = perl_call_sv(CurrentDB->hash, G_SCALAR);
491 croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ;
509 printf ("HASH Info\n") ;
510 printf (" hash = %s\n",
511 (hash->db_HA_hash != NULL ? "redefined" : "default")) ;
512 printf (" bsize = %d\n", hash->db_HA_bsize) ;
513 printf (" ffactor = %d\n", hash->db_HA_ffactor) ;
514 printf (" nelem = %d\n", hash->db_HA_nelem) ;
515 printf (" cachesize = %d\n", hash->db_HA_cachesize) ;
516 printf (" lorder = %d\n", hash->db_HA_lorder) ;
524 printf ("RECNO Info\n") ;
525 printf (" flags = %d\n", recno->db_RE_flags) ;
526 printf (" cachesize = %d\n", recno->db_RE_cachesize) ;
527 printf (" psize = %d\n", recno->db_RE_psize) ;
528 printf (" lorder = %d\n", recno->db_RE_lorder) ;
529 printf (" reclen = %ul\n", (unsigned long)recno->db_RE_reclen) ;
530 printf (" bval = %d 0x%x\n", recno->db_RE_bval, recno->db_RE_bval) ;
531 printf (" bfname = %d [%s]\n", recno->db_RE_bfname, recno->db_RE_bfname) ;
538 printf ("BTREE Info\n") ;
539 printf (" compare = %s\n",
540 (btree->db_BT_compare ? "redefined" : "default")) ;
541 printf (" prefix = %s\n",
542 (btree->db_BT_prefix ? "redefined" : "default")) ;
543 printf (" flags = %d\n", btree->db_BT_flags) ;
544 printf (" cachesize = %d\n", btree->db_BT_cachesize) ;
545 printf (" psize = %d\n", btree->db_BT_psize) ;
546 #ifndef DB_VERSION_MAJOR
547 printf (" maxkeypage = %d\n", btree->db_BT_maxkeypage) ;
548 printf (" minkeypage = %d\n", btree->db_BT_minkeypage) ;
550 printf (" lorder = %d\n", btree->db_BT_lorder) ;
555 #define PrintRecno(recno)
556 #define PrintHash(hash)
557 #define PrintBtree(btree)
572 RETVAL = do_SEQ(db, key, value, R_LAST) ;
574 RETVAL = *(I32 *)key.data ;
575 else /* No key means empty file */
578 return ((I32)RETVAL) ;
582 GetRecnoKey(db, value)
587 /* Get the length of the array */
588 I32 length = GetArrayLength(db) ;
590 /* check for attempt to write before start of array */
591 if (length + value + 1 <= 0)
592 croak("Modification of non-creatable array value attempted, subscript %ld", (long)value) ;
594 value = length + value + 1 ;
603 ParseOpenInfo(isHASH, name, flags, mode, sv)
612 DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ;
613 void * openinfo = NULL ;
614 INFO * info = &RETVAL->info ;
617 /* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
618 Zero(RETVAL, 1, DB_File_type) ;
620 /* Default to HASH */
621 RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
622 RETVAL->type = DB_HASH ;
624 /* DGH - Next line added to avoid SEGV on existing hash DB */
627 /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */
628 RETVAL->in_memory = (name == NULL) ;
633 croak ("type parameter is not a reference") ;
635 svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ;
636 if (svp && SvOK(*svp))
637 action = (HV*) SvRV(*svp) ;
639 croak("internal error") ;
641 if (sv_isa(sv, "DB_File::HASHINFO"))
645 croak("DB_File can only tie an associative array to a DB_HASH database") ;
647 RETVAL->type = DB_HASH ;
648 openinfo = (void*)info ;
650 svp = hv_fetch(action, "hash", 4, FALSE);
652 if (svp && SvOK(*svp))
654 info->db_HA_hash = hash_cb ;
655 RETVAL->hash = newSVsv(*svp) ;
658 info->db_HA_hash = NULL ;
660 svp = hv_fetch(action, "ffactor", 7, FALSE);
661 info->db_HA_ffactor = svp ? SvIV(*svp) : 0;
663 svp = hv_fetch(action, "nelem", 5, FALSE);
664 info->db_HA_nelem = svp ? SvIV(*svp) : 0;
666 svp = hv_fetch(action, "bsize", 5, FALSE);
667 info->db_HA_bsize = svp ? SvIV(*svp) : 0;
669 svp = hv_fetch(action, "cachesize", 9, FALSE);
670 info->db_HA_cachesize = svp ? SvIV(*svp) : 0;
672 svp = hv_fetch(action, "lorder", 6, FALSE);
673 info->db_HA_lorder = svp ? SvIV(*svp) : 0;
677 else if (sv_isa(sv, "DB_File::BTREEINFO"))
680 croak("DB_File can only tie an associative array to a DB_BTREE database");
682 RETVAL->type = DB_BTREE ;
683 openinfo = (void*)info ;
685 svp = hv_fetch(action, "compare", 7, FALSE);
686 if (svp && SvOK(*svp))
688 info->db_BT_compare = btree_compare ;
689 RETVAL->compare = newSVsv(*svp) ;
692 info->db_BT_compare = NULL ;
694 svp = hv_fetch(action, "prefix", 6, FALSE);
695 if (svp && SvOK(*svp))
697 info->db_BT_prefix = btree_prefix ;
698 RETVAL->prefix = newSVsv(*svp) ;
701 info->db_BT_prefix = NULL ;
703 svp = hv_fetch(action, "flags", 5, FALSE);
704 info->db_BT_flags = svp ? SvIV(*svp) : 0;
706 svp = hv_fetch(action, "cachesize", 9, FALSE);
707 info->db_BT_cachesize = svp ? SvIV(*svp) : 0;
709 #ifndef DB_VERSION_MAJOR
710 svp = hv_fetch(action, "minkeypage", 10, FALSE);
711 info->btree.minkeypage = svp ? SvIV(*svp) : 0;
713 svp = hv_fetch(action, "maxkeypage", 10, FALSE);
714 info->btree.maxkeypage = svp ? SvIV(*svp) : 0;
717 svp = hv_fetch(action, "psize", 5, FALSE);
718 info->db_BT_psize = svp ? SvIV(*svp) : 0;
720 svp = hv_fetch(action, "lorder", 6, FALSE);
721 info->db_BT_lorder = svp ? SvIV(*svp) : 0;
726 else if (sv_isa(sv, "DB_File::RECNOINFO"))
729 croak("DB_File can only tie an array to a DB_RECNO database");
731 RETVAL->type = DB_RECNO ;
732 openinfo = (void *)info ;
734 info->db_RE_flags = 0 ;
736 svp = hv_fetch(action, "flags", 5, FALSE);
737 info->db_RE_flags = (u_long) (svp ? SvIV(*svp) : 0);
739 svp = hv_fetch(action, "reclen", 6, FALSE);
740 info->db_RE_reclen = (size_t) (svp ? SvIV(*svp) : 0);
742 svp = hv_fetch(action, "cachesize", 9, FALSE);
743 info->db_RE_cachesize = (u_int) (svp ? SvIV(*svp) : 0);
745 svp = hv_fetch(action, "psize", 5, FALSE);
746 info->db_RE_psize = (u_int) (svp ? SvIV(*svp) : 0);
748 svp = hv_fetch(action, "lorder", 6, FALSE);
749 info->db_RE_lorder = (int) (svp ? SvIV(*svp) : 0);
751 #ifdef DB_VERSION_MAJOR
752 info->re_source = name ;
755 svp = hv_fetch(action, "bfname", 6, FALSE);
756 if (svp && SvOK(*svp)) {
757 char * ptr = SvPV(*svp,n_a) ;
758 #ifdef DB_VERSION_MAJOR
759 name = (char*) n_a ? ptr : NULL ;
761 info->db_RE_bfname = (char*) (n_a ? ptr : NULL) ;
765 #ifdef DB_VERSION_MAJOR
768 info->db_RE_bfname = NULL ;
771 svp = hv_fetch(action, "bval", 4, FALSE);
772 #ifdef DB_VERSION_MAJOR
773 if (svp && SvOK(*svp))
777 value = (int)*SvPV(*svp, n_a) ;
781 if (info->flags & DB_FIXEDLEN) {
782 info->re_pad = value ;
783 info->flags |= DB_PAD ;
786 info->re_delim = value ;
787 info->flags |= DB_DELIMITER ;
792 if (svp && SvOK(*svp))
795 info->db_RE_bval = (u_char)*SvPV(*svp, n_a) ;
797 info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ;
798 DB_flags(info->flags, DB_DELIMITER) ;
803 if (info->db_RE_flags & R_FIXEDLEN)
804 info->db_RE_bval = (u_char) ' ' ;
806 info->db_RE_bval = (u_char) '\n' ;
807 DB_flags(info->flags, DB_DELIMITER) ;
812 info->flags |= DB_RENUMBER ;
818 croak("type is not of type DB_File::HASHINFO, DB_File::BTREEINFO or DB_File::RECNOINFO");
822 /* OS2 Specific Code */
829 #ifdef DB_VERSION_MAJOR
835 /* Map 1.x flags to 2.x flags */
836 if ((flags & O_CREAT) == O_CREAT)
840 if (flags == O_RDONLY)
842 if ((flags & O_RDONLY) == O_RDONLY && (flags & O_RDWR) != O_RDWR)
847 if ((flags & O_TRUNC) == O_TRUNC)
848 Flags |= DB_TRUNCATE ;
851 status = db_open(name, RETVAL->type, Flags, mode, NULL, openinfo, &RETVAL->dbp) ;
853 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
854 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor) ;
856 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor,
865 RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ;
876 croak("DB_File::%s not implemented on this architecture", s);
890 if (strEQ(name, "BTREEMAGIC"))
896 if (strEQ(name, "BTREEVERSION"))
906 if (strEQ(name, "DB_LOCK"))
912 if (strEQ(name, "DB_SHMEM"))
918 if (strEQ(name, "DB_TXN"))
932 if (strEQ(name, "HASHMAGIC"))
938 if (strEQ(name, "HASHVERSION"))
954 if (strEQ(name, "MAX_PAGE_NUMBER"))
955 #ifdef MAX_PAGE_NUMBER
956 return (U32)MAX_PAGE_NUMBER;
960 if (strEQ(name, "MAX_PAGE_OFFSET"))
961 #ifdef MAX_PAGE_OFFSET
962 return MAX_PAGE_OFFSET;
966 if (strEQ(name, "MAX_REC_NUMBER"))
967 #ifdef MAX_REC_NUMBER
968 return (U32)MAX_REC_NUMBER;
982 if (strEQ(name, "RET_ERROR"))
988 if (strEQ(name, "RET_SPECIAL"))
994 if (strEQ(name, "RET_SUCCESS"))
1000 if (strEQ(name, "R_CURSOR"))
1006 if (strEQ(name, "R_DUP"))
1012 if (strEQ(name, "R_FIRST"))
1018 if (strEQ(name, "R_FIXEDLEN"))
1024 if (strEQ(name, "R_IAFTER"))
1030 if (strEQ(name, "R_IBEFORE"))
1036 if (strEQ(name, "R_LAST"))
1042 if (strEQ(name, "R_NEXT"))
1048 if (strEQ(name, "R_NOKEY"))
1054 if (strEQ(name, "R_NOOVERWRITE"))
1055 #ifdef R_NOOVERWRITE
1056 return R_NOOVERWRITE;
1060 if (strEQ(name, "R_PREV"))
1066 if (strEQ(name, "R_RECNOSYNC"))
1072 if (strEQ(name, "R_SETCURSOR"))
1078 if (strEQ(name, "R_SNAPSHOT"))
1112 MODULE = DB_File PACKAGE = DB_File PREFIX = db_
1118 empty.data = &zero ;
1119 empty.size = sizeof(recno_t) ;
1130 db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_HASH)
1137 char * name = (char *) NULL ;
1138 SV * sv = (SV *) NULL ;
1141 if (items >= 3 && SvOK(ST(2)))
1142 name = (char*) SvPV(ST(2), n_a) ;
1147 RETVAL = ParseOpenInfo(isHASH, name, flags, mode, sv) ;
1148 if (RETVAL->dbp == NULL)
1161 SvREFCNT_dec(db->hash) ;
1163 SvREFCNT_dec(db->compare) ;
1165 SvREFCNT_dec(db->prefix) ;
1167 #ifdef DB_VERSION_MAJOR
1174 db_DELETE(db, key, flags=0)
1192 RETVAL = (((db->dbp)->get)(db->dbp, TXN &key, &value, 0) == 0) ;
1198 db_FETCH(db, key, flags=0)
1208 /* RETVAL = ((db->dbp)->get)(db->dbp, TXN &key, &value, flags) ; */
1209 RETVAL = db_get(db, key, value, flags) ;
1210 ST(0) = sv_newmortal();
1211 OutputValue(ST(0), value)
1215 db_STORE(db, key, value, flags=0)
1236 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1237 ST(0) = sv_newmortal();
1238 OutputKey(ST(0), key) ;
1252 RETVAL = do_SEQ(db, key, value, R_NEXT) ;
1253 ST(0) = sv_newmortal();
1254 OutputKey(ST(0), key) ;
1258 # These would be nice for RECNO
1277 #ifdef DB_VERSION_MAJOR
1278 /* get the first value */
1279 RETVAL = do_SEQ(db, key, value, DB_FIRST) ;
1284 for (i = items-1 ; i > 0 ; --i)
1286 value.data = SvPV(ST(i), n_a) ;
1290 key.size = sizeof(int) ;
1291 #ifdef DB_VERSION_MAJOR
1292 RETVAL = (db->cursor->c_put)(db->cursor, &key, &value, DB_BEFORE) ;
1294 RETVAL = (Db->put)(Db, &key, &value, R_IBEFORE) ;
1317 /* First get the final value */
1318 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1319 ST(0) = sv_newmortal();
1323 /* the call to del will trash value, so take a copy now */
1324 OutputValue(ST(0), value) ;
1325 RETVAL = db_del(db, key, R_CURSOR) ;
1327 sv_setsv(ST(0), &PL_sv_undef);
1344 /* get the first value */
1345 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1346 ST(0) = sv_newmortal();
1350 /* the call to del will trash value, so take a copy now */
1351 OutputValue(ST(0), value) ;
1352 RETVAL = db_del(db, key, R_CURSOR) ;
1354 sv_setsv (ST(0), &PL_sv_undef) ;
1366 DBTKEY * keyptr = &key ;
1375 /* Set the Cursor to the Last element */
1376 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1381 #ifdef DB_VERSION_MAJOR
1382 for (i = 1 ; i < items ; ++i)
1385 ++ (* (int*)key.data) ;
1386 value.data = SvPV(ST(i), n_a) ;
1388 RETVAL = (Db->put)(Db, NULL, &key, &value, 0) ;
1393 for (i = items - 1 ; i > 0 ; --i)
1395 value.data = SvPV(ST(i), n_a) ;
1397 RETVAL = (Db->put)(Db, keyptr, &value, R_IAFTER) ;
1411 ALIAS: FETCHSIZE = 1
1414 RETVAL = GetArrayLength(db) ;
1420 # Now provide an interface to the rest of the DB functionality
1424 db_del(db, key, flags=0)
1430 RETVAL = db_del(db, key, flags) ;
1431 #ifdef DB_VERSION_MAJOR
1434 else if (RETVAL == DB_NOTFOUND)
1442 db_get(db, key, value, flags=0)
1450 RETVAL = db_get(db, key, value, flags) ;
1451 #ifdef DB_VERSION_MAJOR
1454 else if (RETVAL == DB_NOTFOUND)
1462 db_put(db, key, value, flags=0)
1469 RETVAL = db_put(db, key, value, flags) ;
1470 #ifdef DB_VERSION_MAJOR
1473 else if (RETVAL == DB_KEYEXIST)
1478 key if (flagSet(flags, R_IAFTER) || flagSet(flags, R_IBEFORE)) OutputKey(ST(1), key);
1486 #ifdef DB_VERSION_MAJOR
1488 status = (db->in_memory
1490 : ((db->dbp)->fd)(db->dbp, &RETVAL) ) ;
1494 RETVAL = (db->in_memory
1496 : ((db->dbp)->fd)(db->dbp) ) ;
1502 db_sync(db, flags=0)
1507 RETVAL = db_sync(db, flags) ;
1508 #ifdef DB_VERSION_MAJOR
1517 db_seq(db, key, value, flags)
1525 RETVAL = db_seq(db, key, value, flags);
1526 #ifdef DB_VERSION_MAJOR
1529 else if (RETVAL == DB_NOTFOUND)