3 DB_File.xs -- Perl 5 interface to Berkeley DB
5 written by Paul Marquess <Paul.Marquess@btinternet.com>
6 last modified 6th March 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
66 1.65 - Fixed a bug in the PUSH logic.
67 Added BOOT check that using 2.3.4 or greater
78 #include "patchlevel.h"
79 #define PERL_REVISION 5
80 #define PERL_VERSION PATCHLEVEL
81 #define PERL_SUBVERSION SUBVERSION
84 #if PERL_REVISION == 5 && (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION <= 75 ))
86 # define PL_sv_undef sv_undef
91 /* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
92 * shortly #included by the <db.h>) __attribute__ to the possibly
93 * already defined __attribute__, for example by GNUC or by Perl. */
97 /* If Perl has been compiled with Threads support,the symbol op will
98 be defined here. This clashes with a field name in db.h, so get rid of it.
111 #ifdef DB_VERSION_MAJOR
113 /* map version 2 features & constants onto their version 1 equivalent */
118 #define DB_Prefix_t size_t
123 #define DB_Hash_t u_int32_t
125 /* DBTYPE stays the same */
126 /* HASHINFO, RECNOINFO and BTREEINFO map to DB_INFO */
127 typedef DB_INFO INFO ;
129 /* version 2 has db_recno_t in place of recno_t */
130 typedef db_recno_t recno_t;
133 #define R_CURSOR DB_SET_RANGE
134 #define R_FIRST DB_FIRST
135 #define R_IAFTER DB_AFTER
136 #define R_IBEFORE DB_BEFORE
137 #define R_LAST DB_LAST
138 #define R_NEXT DB_NEXT
139 #define R_NOOVERWRITE DB_NOOVERWRITE
140 #define R_PREV DB_PREV
141 #define R_SETCURSOR 0
142 #define R_RECNOSYNC 0
143 #define R_FIXEDLEN DB_FIXEDLEN
146 #define db_HA_hash h_hash
147 #define db_HA_ffactor h_ffactor
148 #define db_HA_nelem h_nelem
149 #define db_HA_bsize db_pagesize
150 #define db_HA_cachesize db_cachesize
151 #define db_HA_lorder db_lorder
153 #define db_BT_compare bt_compare
154 #define db_BT_prefix bt_prefix
155 #define db_BT_flags flags
156 #define db_BT_psize db_pagesize
157 #define db_BT_cachesize db_cachesize
158 #define db_BT_lorder db_lorder
159 #define db_BT_maxkeypage
160 #define db_BT_minkeypage
163 #define db_RE_reclen re_len
164 #define db_RE_flags flags
165 #define db_RE_bval re_pad
166 #define db_RE_bfname re_source
167 #define db_RE_psize db_pagesize
168 #define db_RE_cachesize db_cachesize
169 #define db_RE_lorder db_lorder
173 #define do_SEQ(db, key, value, flag) (db->cursor->c_get)(db->cursor, &key, &value, flag)
176 #define DBT_flags(x) x.flags = 0
177 #define DB_flags(x, v) x |= v
179 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
180 #define flagSet(flags, bitmask) ((flags) & (bitmask))
182 #define flagSet(flags, bitmask) (((flags) & DB_OPFLAGS_MASK) == (bitmask))
185 #else /* db version 1.x */
198 #define DB_Prefix_t mDB_Prefix_t
205 #define DB_Hash_t mDB_Hash_t
208 #define db_HA_hash hash.hash
209 #define db_HA_ffactor hash.ffactor
210 #define db_HA_nelem hash.nelem
211 #define db_HA_bsize hash.bsize
212 #define db_HA_cachesize hash.cachesize
213 #define db_HA_lorder hash.lorder
215 #define db_BT_compare btree.compare
216 #define db_BT_prefix btree.prefix
217 #define db_BT_flags btree.flags
218 #define db_BT_psize btree.psize
219 #define db_BT_cachesize btree.cachesize
220 #define db_BT_lorder btree.lorder
221 #define db_BT_maxkeypage btree.maxkeypage
222 #define db_BT_minkeypage btree.minkeypage
224 #define db_RE_reclen recno.reclen
225 #define db_RE_flags recno.flags
226 #define db_RE_bval recno.bval
227 #define db_RE_bfname recno.bfname
228 #define db_RE_psize recno.psize
229 #define db_RE_cachesize recno.cachesize
230 #define db_RE_lorder recno.lorder
234 #define do_SEQ(db, key, value, flag) (db->dbp->seq)(db->dbp, &key, &value, flag)
236 #define DB_flags(x, v)
237 #define flagSet(flags, bitmask) ((flags) & (bitmask))
239 #endif /* db version 1 */
243 #define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, TXN &key, flags)
244 #define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, flags)
245 #define db_FETCH(db, key, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
247 #define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags)
248 #define db_get(db, key, value, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
250 #ifdef DB_VERSION_MAJOR
251 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp, 0)
252 #define db_close(db) ((db->dbp)->close)(db->dbp, 0)
253 #define db_del(db, key, flags) (flagSet(flags, R_CURSOR) \
254 ? ((db->cursor)->c_del)(db->cursor, 0) \
255 : ((db->dbp)->del)(db->dbp, NULL, &key, flags) )
259 #define db_DESTROY(db) ((db->dbp)->close)(db->dbp)
260 #define db_close(db) ((db->dbp)->close)(db->dbp)
261 #define db_del(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags)
262 #define db_put(db, key, value, flags) ((db->dbp)->put)(db->dbp, &key, &value, flags)
267 #define db_seq(db, key, value, flags) do_SEQ(db, key, value, flags)
277 #ifdef DB_VERSION_MAJOR
282 typedef DB_File_type * DB_File ;
285 #define my_sv_setpvn(sv, d, s) sv_setpvn(sv, (s ? d : (void*)""), s)
287 #define OutputValue(arg, name) \
288 { if (RETVAL == 0) { \
289 my_sv_setpvn(arg, name.data, name.size) ; \
293 #define OutputKey(arg, name) \
296 if (db->type != DB_RECNO) { \
297 my_sv_setpvn(arg, name.data, name.size); \
300 sv_setiv(arg, (I32)*(I32*)name.data - 1); \
305 /* Internal Global Data */
306 static recno_t Value ;
307 static recno_t zero = 0 ;
308 static DB_File CurrentDB ;
309 static DBTKEY empty ;
311 #ifdef DB_VERSION_MAJOR
314 db_put(db, key, value, flags)
323 if (flagSet(flags, R_CURSOR)) {
324 status = ((db->cursor)->c_del)(db->cursor, 0);
328 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
331 flags &= ~DB_OPFLAGS_MASK ;
336 return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;
340 #endif /* DB_VERSION_MAJOR */
345 SV * ver_sv = perl_get_sv("DB_File::db_version", TRUE) ;
346 #ifdef DB_VERSION_MAJOR
347 int Major, Minor, Patch ;
349 (void)db_version(&Major, &Minor, &Patch) ;
351 /* check that libdb is recent enough -- we need 2.3.4 or greater */
352 if (Major == 2 && (Minor < 3 || (Minor == 3 && Patch < 4)))
353 croak("DB_File needs Berkeley DB 2.3.4 or greater, you have %d.%d.%d\n",
354 Major, Minor, Patch) ;
357 sv_setpvf(ver_sv, "%d.%d", Major, Minor) ;
361 sprintf(buffer, "%d.%d", Major, Minor) ;
362 sv_setpv(ver_sv, buffer) ;
367 sv_setiv(ver_sv, 1) ;
374 btree_compare(key1, key2)
379 void * data1, * data2 ;
386 /* As newSVpv will assume that the data pointer is a null terminated C
387 string if the size parameter is 0, make sure that data points to an
388 empty string if the length is 0
400 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
401 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
404 count = perl_call_sv(CurrentDB->compare, G_SCALAR);
409 croak ("DB_File btree_compare: expected 1 return value from compare sub, got %d\n", count) ;
421 btree_prefix(key1, key2)
426 void * data1, * data2 ;
433 /* As newSVpv will assume that the data pointer is a null terminated C
434 string if the size parameter is 0, make sure that data points to an
435 empty string if the length is 0
447 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
448 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
451 count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
456 croak ("DB_File btree_prefix: expected 1 return value from prefix sub, got %d\n", count) ;
479 /* DGH - Next two lines added to fix corrupted stack problem */
485 XPUSHs(sv_2mortal(newSVpv((char*)data,size)));
488 count = perl_call_sv(CurrentDB->hash, G_SCALAR);
493 croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ;
511 printf ("HASH Info\n") ;
512 printf (" hash = %s\n",
513 (hash->db_HA_hash != NULL ? "redefined" : "default")) ;
514 printf (" bsize = %d\n", hash->db_HA_bsize) ;
515 printf (" ffactor = %d\n", hash->db_HA_ffactor) ;
516 printf (" nelem = %d\n", hash->db_HA_nelem) ;
517 printf (" cachesize = %d\n", hash->db_HA_cachesize) ;
518 printf (" lorder = %d\n", hash->db_HA_lorder) ;
526 printf ("RECNO Info\n") ;
527 printf (" flags = %d\n", recno->db_RE_flags) ;
528 printf (" cachesize = %d\n", recno->db_RE_cachesize) ;
529 printf (" psize = %d\n", recno->db_RE_psize) ;
530 printf (" lorder = %d\n", recno->db_RE_lorder) ;
531 printf (" reclen = %ul\n", (unsigned long)recno->db_RE_reclen) ;
532 printf (" bval = %d 0x%x\n", recno->db_RE_bval, recno->db_RE_bval) ;
533 printf (" bfname = %d [%s]\n", recno->db_RE_bfname, recno->db_RE_bfname) ;
540 printf ("BTREE Info\n") ;
541 printf (" compare = %s\n",
542 (btree->db_BT_compare ? "redefined" : "default")) ;
543 printf (" prefix = %s\n",
544 (btree->db_BT_prefix ? "redefined" : "default")) ;
545 printf (" flags = %d\n", btree->db_BT_flags) ;
546 printf (" cachesize = %d\n", btree->db_BT_cachesize) ;
547 printf (" psize = %d\n", btree->db_BT_psize) ;
548 #ifndef DB_VERSION_MAJOR
549 printf (" maxkeypage = %d\n", btree->db_BT_maxkeypage) ;
550 printf (" minkeypage = %d\n", btree->db_BT_minkeypage) ;
552 printf (" lorder = %d\n", btree->db_BT_lorder) ;
557 #define PrintRecno(recno)
558 #define PrintHash(hash)
559 #define PrintBtree(btree)
574 RETVAL = do_SEQ(db, key, value, R_LAST) ;
576 RETVAL = *(I32 *)key.data ;
577 else /* No key means empty file */
580 return ((I32)RETVAL) ;
584 GetRecnoKey(db, value)
589 /* Get the length of the array */
590 I32 length = GetArrayLength(db) ;
592 /* check for attempt to write before start of array */
593 if (length + value + 1 <= 0)
594 croak("Modification of non-creatable array value attempted, subscript %ld", (long)value) ;
596 value = length + value + 1 ;
605 ParseOpenInfo(isHASH, name, flags, mode, sv)
614 DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ;
615 void * openinfo = NULL ;
616 INFO * info = &RETVAL->info ;
619 /* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
620 Zero(RETVAL, 1, DB_File_type) ;
622 /* Default to HASH */
623 RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
624 RETVAL->type = DB_HASH ;
626 /* DGH - Next line added to avoid SEGV on existing hash DB */
629 /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */
630 RETVAL->in_memory = (name == NULL) ;
635 croak ("type parameter is not a reference") ;
637 svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ;
638 if (svp && SvOK(*svp))
639 action = (HV*) SvRV(*svp) ;
641 croak("internal error") ;
643 if (sv_isa(sv, "DB_File::HASHINFO"))
647 croak("DB_File can only tie an associative array to a DB_HASH database") ;
649 RETVAL->type = DB_HASH ;
650 openinfo = (void*)info ;
652 svp = hv_fetch(action, "hash", 4, FALSE);
654 if (svp && SvOK(*svp))
656 info->db_HA_hash = hash_cb ;
657 RETVAL->hash = newSVsv(*svp) ;
660 info->db_HA_hash = NULL ;
662 svp = hv_fetch(action, "ffactor", 7, FALSE);
663 info->db_HA_ffactor = svp ? SvIV(*svp) : 0;
665 svp = hv_fetch(action, "nelem", 5, FALSE);
666 info->db_HA_nelem = svp ? SvIV(*svp) : 0;
668 svp = hv_fetch(action, "bsize", 5, FALSE);
669 info->db_HA_bsize = svp ? SvIV(*svp) : 0;
671 svp = hv_fetch(action, "cachesize", 9, FALSE);
672 info->db_HA_cachesize = svp ? SvIV(*svp) : 0;
674 svp = hv_fetch(action, "lorder", 6, FALSE);
675 info->db_HA_lorder = svp ? SvIV(*svp) : 0;
679 else if (sv_isa(sv, "DB_File::BTREEINFO"))
682 croak("DB_File can only tie an associative array to a DB_BTREE database");
684 RETVAL->type = DB_BTREE ;
685 openinfo = (void*)info ;
687 svp = hv_fetch(action, "compare", 7, FALSE);
688 if (svp && SvOK(*svp))
690 info->db_BT_compare = btree_compare ;
691 RETVAL->compare = newSVsv(*svp) ;
694 info->db_BT_compare = NULL ;
696 svp = hv_fetch(action, "prefix", 6, FALSE);
697 if (svp && SvOK(*svp))
699 info->db_BT_prefix = btree_prefix ;
700 RETVAL->prefix = newSVsv(*svp) ;
703 info->db_BT_prefix = NULL ;
705 svp = hv_fetch(action, "flags", 5, FALSE);
706 info->db_BT_flags = svp ? SvIV(*svp) : 0;
708 svp = hv_fetch(action, "cachesize", 9, FALSE);
709 info->db_BT_cachesize = svp ? SvIV(*svp) : 0;
711 #ifndef DB_VERSION_MAJOR
712 svp = hv_fetch(action, "minkeypage", 10, FALSE);
713 info->btree.minkeypage = svp ? SvIV(*svp) : 0;
715 svp = hv_fetch(action, "maxkeypage", 10, FALSE);
716 info->btree.maxkeypage = svp ? SvIV(*svp) : 0;
719 svp = hv_fetch(action, "psize", 5, FALSE);
720 info->db_BT_psize = svp ? SvIV(*svp) : 0;
722 svp = hv_fetch(action, "lorder", 6, FALSE);
723 info->db_BT_lorder = svp ? SvIV(*svp) : 0;
728 else if (sv_isa(sv, "DB_File::RECNOINFO"))
731 croak("DB_File can only tie an array to a DB_RECNO database");
733 RETVAL->type = DB_RECNO ;
734 openinfo = (void *)info ;
736 info->db_RE_flags = 0 ;
738 svp = hv_fetch(action, "flags", 5, FALSE);
739 info->db_RE_flags = (u_long) (svp ? SvIV(*svp) : 0);
741 svp = hv_fetch(action, "reclen", 6, FALSE);
742 info->db_RE_reclen = (size_t) (svp ? SvIV(*svp) : 0);
744 svp = hv_fetch(action, "cachesize", 9, FALSE);
745 info->db_RE_cachesize = (u_int) (svp ? SvIV(*svp) : 0);
747 svp = hv_fetch(action, "psize", 5, FALSE);
748 info->db_RE_psize = (u_int) (svp ? SvIV(*svp) : 0);
750 svp = hv_fetch(action, "lorder", 6, FALSE);
751 info->db_RE_lorder = (int) (svp ? SvIV(*svp) : 0);
753 #ifdef DB_VERSION_MAJOR
754 info->re_source = name ;
757 svp = hv_fetch(action, "bfname", 6, FALSE);
758 if (svp && SvOK(*svp)) {
759 char * ptr = SvPV(*svp,n_a) ;
760 #ifdef DB_VERSION_MAJOR
761 name = (char*) n_a ? ptr : NULL ;
763 info->db_RE_bfname = (char*) (n_a ? ptr : NULL) ;
767 #ifdef DB_VERSION_MAJOR
770 info->db_RE_bfname = NULL ;
773 svp = hv_fetch(action, "bval", 4, FALSE);
774 #ifdef DB_VERSION_MAJOR
775 if (svp && SvOK(*svp))
779 value = (int)*SvPV(*svp, n_a) ;
783 if (info->flags & DB_FIXEDLEN) {
784 info->re_pad = value ;
785 info->flags |= DB_PAD ;
788 info->re_delim = value ;
789 info->flags |= DB_DELIMITER ;
794 if (svp && SvOK(*svp))
797 info->db_RE_bval = (u_char)*SvPV(*svp, n_a) ;
799 info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ;
800 DB_flags(info->flags, DB_DELIMITER) ;
805 if (info->db_RE_flags & R_FIXEDLEN)
806 info->db_RE_bval = (u_char) ' ' ;
808 info->db_RE_bval = (u_char) '\n' ;
809 DB_flags(info->flags, DB_DELIMITER) ;
814 info->flags |= DB_RENUMBER ;
820 croak("type is not of type DB_File::HASHINFO, DB_File::BTREEINFO or DB_File::RECNOINFO");
824 /* OS2 Specific Code */
831 #ifdef DB_VERSION_MAJOR
837 /* Map 1.x flags to 2.x flags */
838 if ((flags & O_CREAT) == O_CREAT)
842 if (flags == O_RDONLY)
844 if ((flags & O_RDONLY) == O_RDONLY && (flags & O_RDWR) != O_RDWR)
849 if ((flags & O_TRUNC) == O_TRUNC)
850 Flags |= DB_TRUNCATE ;
853 status = db_open(name, RETVAL->type, Flags, mode, NULL, openinfo, &RETVAL->dbp) ;
855 #if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
856 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor) ;
858 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor,
867 RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ;
878 croak("DB_File::%s not implemented on this architecture", s);
892 if (strEQ(name, "BTREEMAGIC"))
898 if (strEQ(name, "BTREEVERSION"))
908 if (strEQ(name, "DB_LOCK"))
914 if (strEQ(name, "DB_SHMEM"))
920 if (strEQ(name, "DB_TXN"))
934 if (strEQ(name, "HASHMAGIC"))
940 if (strEQ(name, "HASHVERSION"))
956 if (strEQ(name, "MAX_PAGE_NUMBER"))
957 #ifdef MAX_PAGE_NUMBER
958 return (U32)MAX_PAGE_NUMBER;
962 if (strEQ(name, "MAX_PAGE_OFFSET"))
963 #ifdef MAX_PAGE_OFFSET
964 return MAX_PAGE_OFFSET;
968 if (strEQ(name, "MAX_REC_NUMBER"))
969 #ifdef MAX_REC_NUMBER
970 return (U32)MAX_REC_NUMBER;
984 if (strEQ(name, "RET_ERROR"))
990 if (strEQ(name, "RET_SPECIAL"))
996 if (strEQ(name, "RET_SUCCESS"))
1002 if (strEQ(name, "R_CURSOR"))
1008 if (strEQ(name, "R_DUP"))
1014 if (strEQ(name, "R_FIRST"))
1020 if (strEQ(name, "R_FIXEDLEN"))
1026 if (strEQ(name, "R_IAFTER"))
1032 if (strEQ(name, "R_IBEFORE"))
1038 if (strEQ(name, "R_LAST"))
1044 if (strEQ(name, "R_NEXT"))
1050 if (strEQ(name, "R_NOKEY"))
1056 if (strEQ(name, "R_NOOVERWRITE"))
1057 #ifdef R_NOOVERWRITE
1058 return R_NOOVERWRITE;
1062 if (strEQ(name, "R_PREV"))
1068 if (strEQ(name, "R_RECNOSYNC"))
1074 if (strEQ(name, "R_SETCURSOR"))
1080 if (strEQ(name, "R_SNAPSHOT"))
1114 MODULE = DB_File PACKAGE = DB_File PREFIX = db_
1120 empty.data = &zero ;
1121 empty.size = sizeof(recno_t) ;
1132 db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_HASH)
1139 char * name = (char *) NULL ;
1140 SV * sv = (SV *) NULL ;
1143 if (items >= 3 && SvOK(ST(2)))
1144 name = (char*) SvPV(ST(2), n_a) ;
1149 RETVAL = ParseOpenInfo(isHASH, name, flags, mode, sv) ;
1150 if (RETVAL->dbp == NULL)
1163 SvREFCNT_dec(db->hash) ;
1165 SvREFCNT_dec(db->compare) ;
1167 SvREFCNT_dec(db->prefix) ;
1169 #ifdef DB_VERSION_MAJOR
1176 db_DELETE(db, key, flags=0)
1194 RETVAL = (((db->dbp)->get)(db->dbp, TXN &key, &value, 0) == 0) ;
1200 db_FETCH(db, key, flags=0)
1210 /* RETVAL = ((db->dbp)->get)(db->dbp, TXN &key, &value, flags) ; */
1211 RETVAL = db_get(db, key, value, flags) ;
1212 ST(0) = sv_newmortal();
1213 OutputValue(ST(0), value)
1217 db_STORE(db, key, value, flags=0)
1237 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1238 ST(0) = sv_newmortal();
1239 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) ;
1316 /* First get the final value */
1317 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1318 ST(0) = sv_newmortal();
1322 /* the call to del will trash value, so take a copy now */
1323 OutputValue(ST(0), value) ;
1324 RETVAL = db_del(db, key, R_CURSOR) ;
1326 sv_setsv(ST(0), &PL_sv_undef);
1342 /* get the first value */
1343 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
1344 ST(0) = sv_newmortal();
1348 /* the call to del will trash value, so take a copy now */
1349 OutputValue(ST(0), value) ;
1350 RETVAL = db_del(db, key, R_CURSOR) ;
1352 sv_setsv (ST(0), &PL_sv_undef) ;
1372 #ifdef DB_VERSION_MAJOR
1375 for (i = 1 ; i < items ; ++i)
1377 value.data = SvPV(ST(i), n_a) ;
1379 RETVAL = (Db->put)(Db, NULL, &key, &value, DB_APPEND) ;
1384 /* Set the Cursor to the Last element */
1385 RETVAL = do_SEQ(db, key, value, R_LAST) ;
1390 for (i = items - 1 ; i > 0 ; --i)
1392 value.data = SvPV(ST(i), n_a) ;
1394 RETVAL = (Db->put)(Db, &key, &value, R_IAFTER) ;
1408 ALIAS: FETCHSIZE = 1
1411 RETVAL = GetArrayLength(db) ;
1417 # Now provide an interface to the rest of the DB functionality
1421 db_del(db, key, flags=0)
1427 RETVAL = db_del(db, key, flags) ;
1428 #ifdef DB_VERSION_MAJOR
1431 else if (RETVAL == DB_NOTFOUND)
1439 db_get(db, key, value, flags=0)
1447 RETVAL = db_get(db, key, value, flags) ;
1448 #ifdef DB_VERSION_MAJOR
1451 else if (RETVAL == DB_NOTFOUND)
1459 db_put(db, key, value, flags=0)
1466 RETVAL = db_put(db, key, value, flags) ;
1467 #ifdef DB_VERSION_MAJOR
1470 else if (RETVAL == DB_KEYEXIST)
1475 key if (flagSet(flags, R_IAFTER) || flagSet(flags, R_IBEFORE)) OutputKey(ST(1), key);
1483 #ifdef DB_VERSION_MAJOR
1485 status = (db->in_memory
1487 : ((db->dbp)->fd)(db->dbp, &RETVAL) ) ;
1491 RETVAL = (db->in_memory
1493 : ((db->dbp)->fd)(db->dbp) ) ;
1499 db_sync(db, flags=0)
1504 RETVAL = db_sync(db, flags) ;
1505 #ifdef DB_VERSION_MAJOR
1514 db_seq(db, key, value, flags)
1522 RETVAL = db_seq(db, key, value, flags);
1523 #ifdef DB_VERSION_MAJOR
1526 else if (RETVAL == DB_NOTFOUND)