fix coredump after 64k-deep recursion
[p5sagit/p5-mst-13.2.git] / ext / DB_File / DB_File.xs
CommitLineData
a0d0e21e 1/*
2
3 DB_File.xs -- Perl 5 interface to Berkeley DB
4
6ca2e664 5 written by Paul Marquess <Paul.Marquess@btinternet.com>
962cee9f 6 last modified 1st March 2002
7 version 1.803
a0d0e21e 8
9 All comments/suggestions/problems are welcome
10
d63909e4 11 Copyright (c) 1995-2002 Paul Marquess. All rights reserved.
36477c24 12 This program is free software; you can redistribute it and/or
13 modify it under the same terms as Perl itself.
14
3b35bae3 15 Changes:
4633a7c4 16 0.1 - Initial Release
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.
88108326 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
f6b705ef 29 1.03 - Added EXISTS
610ab055 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
33 Makefile.PL
ff68c719 34 1.06 - Minor namespace cleanup: Localized PrintBtree.
36477c24 35 1.07 - Fixed bug with RECNO, where bval wasn't defaulting to "\n".
36 1.08 - No change to DB_File.xs
18d2dc8c 37 1.09 - Default mode for dbopen changed to 0666
a0b8c8c1 38 1.10 - Fixed fd method so that it still returns -1 for
39 in-memory files when db 1.86 is used.
778183f3 40 1.11 - No change to DB_File.xs
68dc0745 41 1.12 - No change to DB_File.xs
1f70e1ea 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
a6ed719b 48 undefined value" warning with db_get and db_seq.
1f70e1ea 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
045291aa 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.
a9fd575d 57 1.59 - No change to DB_File.xs
58 1.60 - Some code tidy up
9d9477b1 59 1.61 - added flagSet macro for DB 2.5.x
60 fixed typo in O_RDONLY test.
6ca2e664 61 1.62 - No change to DB_File.xs
62 1.63 - Fix to alllow DB 2.6.x to build.
20896112 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
ca63f0d2 66 1.65 - Fixed a bug in the PUSH logic.
67 Added BOOT check that using 2.3.4 or greater
9fe6733a 68 1.66 - Added DBM filter code
cad2e5aa 69 1.67 - Backed off the use of newSVpvn.
70 Fixed DBM Filter code for Perl 5.004.
71 Fixed a small memory leak in the filter code.
2c2d71f5 72 1.68 - fixed backward compatability bug with R_IAFTER & R_IBEFORE
73 merged in the 5.005_58 changes
a62982a8 74 1.69 - fixed a bug in push -- DB_APPEND wasn't working properly.
75 Fixed the R_SETCURSOR bug introduced in 1.68
76 Added a new Perl variable $DB_File::db_ver
e07e3419 77 1.70 - Initialise $DB_File::db_ver and $DB_File::db_version with
78 GV_ADD|GV_ADDMULT -- bug spotted by Nick Ing-Simmons.
79 Added a BOOT check to test for equivalent versions of db.h &
80 libdb.a/so.
ccb44e3b 81 1.71 - Support for Berkeley DB version 3.
82 Support for Berkeley DB 2/3's backward compatability mode.
83 Rewrote push
b90e71be 84 1.72 - No change to DB_File.xs
88c74d4b 85 1.73 - No change to DB_File.xs
3245f058 86 1.74 - A call to open needed parenthesised to stop it clashing
87 with a win32 macro.
88 Added Perl core patches 7703 & 7801.
73969f8f 89 1.75 - Fixed Perl core patch 7703.
90 Added suppport to allow DB_File to be built with
91 Berkeley DB 3.2 -- btree_compare, btree_prefix and hash_cb
92 needed to be changed.
c5da4faf 93 1.76 - No change to DB_File.xs
94 1.77 - Tidied up a few types used in calling newSVpvn.
39793c41 95 1.78 - Core patch 10335, 10372, 10534, 10549, 11051 included.
c6c92ad9 96 1.79 - NEXTKEY ignores the input key.
97 Added lots of casts
07200f1b 98 1.800 - Moved backward compatability code into ppport.h.
99 Use the new constants code.
412e9c57 100 1.801 - No change to DB_File.xs
d63909e4 101 1.802 - No change to DB_File.xs
962cee9f 102 1.803 - FETCH, STORE & DELETE don't map the flags parameter
103 into the equivalent Berkeley DB function anymore.
f6b705ef 104
a0d0e21e 105*/
106
c6c619a9 107#define PERL_NO_GET_CONTEXT
a0d0e21e 108#include "EXTERN.h"
109#include "perl.h"
110#include "XSUB.h"
111
07200f1b 112#ifdef _NOT_CORE
113# include "ppport.h"
cad2e5aa 114#endif
115
640374d0 116/* Mention DB_VERSION_MAJOR_CFG, DB_VERSION_MINOR_CFG, and
117 DB_VERSION_PATCH_CFG here so that Configure pulls them all in. */
118
52e1cb5e 119/* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
120 * shortly #included by the <db.h>) __attribute__ to the possibly
121 * already defined __attribute__, for example by GNUC or by Perl. */
1f70e1ea 122
39793c41 123/* #if DB_VERSION_MAJOR_CFG < 2 */
124#ifndef DB_VERSION_MAJOR
125# undef __attribute__
640374d0 126#endif
127
ccb44e3b 128#ifdef COMPAT185
129# include <db_185.h>
130#else
131# include <db.h>
132#endif
a0d0e21e 133
39793c41 134/* Wall starts with 5.7.x */
135
136#if PERL_REVISION > 5 || (PERL_REVISION == 5 && PERL_VERSION >= 7)
137
138/* Since we dropped the gccish definition of __attribute__ we will want
139 * to redefine dNOOP, however (so that dTHX continues to work). Yes,
140 * all this means that we can't do attribute checking on the DB_File,
141 * boo, hiss. */
142# ifndef DB_VERSION_MAJOR
143
144# undef dNOOP
145# define dNOOP extern int Perl___notused
146
147 /* Ditto for dXSARGS. */
148# undef dXSARGS
149# define dXSARGS \
150 dSP; dMARK; \
151 I32 ax = mark - PL_stack_base + 1; \
152 I32 items = sp - mark
153
154# endif
155
156/* avoid -Wall; DB_File xsubs never make use of `ix' setup for ALIASes */
157# undef dXSI32
158# define dXSI32 dNOOP
159
160#endif /* Perl >= 5.7 */
b92372bc 161
a0d0e21e 162#include <fcntl.h>
163
1f70e1ea 164/* #define TRACE */
165
ccb44e3b 166#ifdef TRACE
167# define Trace(x) printf x
168#else
169# define Trace(x)
170#endif
171
1f70e1ea 172
ccb44e3b 173#define DBT_clear(x) Zero(&x, 1, DBT) ;
1f70e1ea 174
175#ifdef DB_VERSION_MAJOR
176
ccb44e3b 177#if DB_VERSION_MAJOR == 2
178# define BERKELEY_DB_1_OR_2
179#endif
180
73969f8f 181#if DB_VERSION_MAJOR > 3 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 2)
182# define AT_LEAST_DB_3_2
183#endif
184
1f70e1ea 185/* map version 2 features & constants onto their version 1 equivalent */
186
187#ifdef DB_Prefix_t
2c2d71f5 188# undef DB_Prefix_t
1f70e1ea 189#endif
190#define DB_Prefix_t size_t
191
192#ifdef DB_Hash_t
2c2d71f5 193# undef DB_Hash_t
1f70e1ea 194#endif
195#define DB_Hash_t u_int32_t
196
197/* DBTYPE stays the same */
198/* HASHINFO, RECNOINFO and BTREEINFO map to DB_INFO */
ccb44e3b 199#if DB_VERSION_MAJOR == 2
200 typedef DB_INFO INFO ;
201#else /* DB_VERSION_MAJOR > 2 */
202# define DB_FIXEDLEN (0x8000)
203#endif /* DB_VERSION_MAJOR == 2 */
1f70e1ea 204
205/* version 2 has db_recno_t in place of recno_t */
206typedef db_recno_t recno_t;
207
208
209#define R_CURSOR DB_SET_RANGE
210#define R_FIRST DB_FIRST
211#define R_IAFTER DB_AFTER
212#define R_IBEFORE DB_BEFORE
213#define R_LAST DB_LAST
214#define R_NEXT DB_NEXT
215#define R_NOOVERWRITE DB_NOOVERWRITE
216#define R_PREV DB_PREV
ccb44e3b 217
a62982a8 218#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
ccb44e3b 219# define R_SETCURSOR 0x800000
a62982a8 220#else
ccb44e3b 221# define R_SETCURSOR (-100)
a62982a8 222#endif
ccb44e3b 223
1f70e1ea 224#define R_RECNOSYNC 0
225#define R_FIXEDLEN DB_FIXEDLEN
226#define R_DUP DB_DUP
227
ccb44e3b 228
1f70e1ea 229#define db_HA_hash h_hash
230#define db_HA_ffactor h_ffactor
231#define db_HA_nelem h_nelem
232#define db_HA_bsize db_pagesize
233#define db_HA_cachesize db_cachesize
234#define db_HA_lorder db_lorder
235
236#define db_BT_compare bt_compare
237#define db_BT_prefix bt_prefix
238#define db_BT_flags flags
239#define db_BT_psize db_pagesize
240#define db_BT_cachesize db_cachesize
241#define db_BT_lorder db_lorder
242#define db_BT_maxkeypage
243#define db_BT_minkeypage
244
245
246#define db_RE_reclen re_len
247#define db_RE_flags flags
248#define db_RE_bval re_pad
249#define db_RE_bfname re_source
250#define db_RE_psize db_pagesize
251#define db_RE_cachesize db_cachesize
252#define db_RE_lorder db_lorder
253
254#define TXN NULL,
255
256#define do_SEQ(db, key, value, flag) (db->cursor->c_get)(db->cursor, &key, &value, flag)
257
258
259#define DBT_flags(x) x.flags = 0
260#define DB_flags(x, v) x |= v
261
9d9477b1 262#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
ccb44e3b 263# define flagSet(flags, bitmask) ((flags) & (bitmask))
9d9477b1 264#else
ccb44e3b 265# define flagSet(flags, bitmask) (((flags) & DB_OPFLAGS_MASK) == (bitmask))
9d9477b1 266#endif
267
1f70e1ea 268#else /* db version 1.x */
269
73969f8f 270#define BERKELEY_DB_1
ccb44e3b 271#define BERKELEY_DB_1_OR_2
272
1f70e1ea 273typedef union INFO {
274 HASHINFO hash ;
275 RECNOINFO recno ;
276 BTREEINFO btree ;
277 } INFO ;
278
279
610ab055 280#ifdef mDB_Prefix_t
ccb44e3b 281# ifdef DB_Prefix_t
282# undef DB_Prefix_t
283# endif
284# define DB_Prefix_t mDB_Prefix_t
610ab055 285#endif
286
287#ifdef mDB_Hash_t
ccb44e3b 288# ifdef DB_Hash_t
289# undef DB_Hash_t
290# endif
291# define DB_Hash_t mDB_Hash_t
610ab055 292#endif
293
1f70e1ea 294#define db_HA_hash hash.hash
295#define db_HA_ffactor hash.ffactor
296#define db_HA_nelem hash.nelem
297#define db_HA_bsize hash.bsize
298#define db_HA_cachesize hash.cachesize
299#define db_HA_lorder hash.lorder
300
301#define db_BT_compare btree.compare
302#define db_BT_prefix btree.prefix
303#define db_BT_flags btree.flags
304#define db_BT_psize btree.psize
305#define db_BT_cachesize btree.cachesize
306#define db_BT_lorder btree.lorder
307#define db_BT_maxkeypage btree.maxkeypage
308#define db_BT_minkeypage btree.minkeypage
309
310#define db_RE_reclen recno.reclen
311#define db_RE_flags recno.flags
312#define db_RE_bval recno.bval
313#define db_RE_bfname recno.bfname
314#define db_RE_psize recno.psize
315#define db_RE_cachesize recno.cachesize
316#define db_RE_lorder recno.lorder
317
318#define TXN
319
320#define do_SEQ(db, key, value, flag) (db->dbp->seq)(db->dbp, &key, &value, flag)
321#define DBT_flags(x)
322#define DB_flags(x, v)
9d9477b1 323#define flagSet(flags, bitmask) ((flags) & (bitmask))
1f70e1ea 324
325#endif /* db version 1 */
326
327
328
962cee9f 329#define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, TXN &key, 0)
330#define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, 0)
331#define db_FETCH(db, key, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, 0)
1f70e1ea 332
333#define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags)
334#define db_get(db, key, value, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
9d9477b1 335
1f70e1ea 336#ifdef DB_VERSION_MAJOR
a62982a8 337#define db_DESTROY(db) ( db->cursor->c_close(db->cursor),\
ccb44e3b 338 (db->dbp->close)(db->dbp, 0) )
1f70e1ea 339#define db_close(db) ((db->dbp)->close)(db->dbp, 0)
9d9477b1 340#define db_del(db, key, flags) (flagSet(flags, R_CURSOR) \
1f70e1ea 341 ? ((db->cursor)->c_del)(db->cursor, 0) \
342 : ((db->dbp)->del)(db->dbp, NULL, &key, flags) )
343
ccb44e3b 344#else /* ! DB_VERSION_MAJOR */
1f70e1ea 345
346#define db_DESTROY(db) ((db->dbp)->close)(db->dbp)
347#define db_close(db) ((db->dbp)->close)(db->dbp)
348#define db_del(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags)
349#define db_put(db, key, value, flags) ((db->dbp)->put)(db->dbp, &key, &value, flags)
350
ccb44e3b 351#endif /* ! DB_VERSION_MAJOR */
1f70e1ea 352
9d9477b1 353
1f70e1ea 354#define db_seq(db, key, value, flags) do_SEQ(db, key, value, flags)
610ab055 355
8e07c86e 356typedef struct {
357 DBTYPE type ;
358 DB * dbp ;
359 SV * compare ;
360 SV * prefix ;
361 SV * hash ;
a0b8c8c1 362 int in_memory ;
ccb44e3b 363#ifdef BERKELEY_DB_1_OR_2
1f70e1ea 364 INFO info ;
ccb44e3b 365#endif
1f70e1ea 366#ifdef DB_VERSION_MAJOR
367 DBC * cursor ;
368#endif
9fe6733a 369 SV * filter_fetch_key ;
370 SV * filter_store_key ;
371 SV * filter_fetch_value ;
372 SV * filter_store_value ;
373 int filtering ;
9fe6733a 374
8e07c86e 375 } DB_File_type;
376
377typedef DB_File_type * DB_File ;
a0d0e21e 378typedef DBT DBTKEY ;
379
045291aa 380#define my_sv_setpvn(sv, d, s) sv_setpvn(sv, (s ? d : (void*)""), s)
a0d0e21e 381
9fe6733a 382#define OutputValue(arg, name) \
383 { if (RETVAL == 0) { \
384 my_sv_setpvn(arg, name.data, name.size) ; \
6a31061a 385 DBM_ckFilter(arg, filter_fetch_value,"filter_fetch_value") ; \
9fe6733a 386 } \
88108326 387 }
a0d0e21e 388
9fe6733a 389#define OutputKey(arg, name) \
390 { if (RETVAL == 0) \
391 { \
392 if (db->type != DB_RECNO) { \
393 my_sv_setpvn(arg, name.data, name.size); \
394 } \
395 else \
396 sv_setiv(arg, (I32)*(I32*)name.data - 1); \
6a31061a 397 DBM_ckFilter(arg, filter_fetch_key,"filter_fetch_key") ; \
9fe6733a 398 } \
a0d0e21e 399 }
400
c6c92ad9 401#define my_SvUV32(sv) ((u_int32_t)SvUV(sv))
045291aa 402
39793c41 403#ifdef CAN_PROTOTYPE
404extern void __getBerkeleyDBInfo(void);
405#endif
406
a0d0e21e 407/* Internal Global Data */
07200f1b 408
df3728a2 409#define MY_CXT_KEY "DB_File::_guts" XS_VERSION
410
411typedef struct {
412 recno_t x_Value;
413 recno_t x_zero;
414 DB_File x_CurrentDB;
415 DBTKEY x_empty;
416} my_cxt_t;
417
418START_MY_CXT
419
420#define Value (MY_CXT.x_Value)
421#define zero (MY_CXT.x_zero)
422#define CurrentDB (MY_CXT.x_CurrentDB)
423#define empty (MY_CXT.x_empty)
1f70e1ea 424
425#ifdef DB_VERSION_MAJOR
426
427static int
2c2d71f5 428#ifdef CAN_PROTOTYPE
b76802f5 429db_put(DB_File db, DBTKEY key, DBT value, u_int flags)
2c2d71f5 430#else
431db_put(db, key, value, flags)
432DB_File db ;
433DBTKEY key ;
434DBT value ;
435u_int flags ;
436#endif
1f70e1ea 437{
438 int status ;
439
2c2d71f5 440 if (flagSet(flags, R_IAFTER) || flagSet(flags, R_IBEFORE)) {
441 DBC * temp_cursor ;
442 DBT l_key, l_value;
443
444#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
445 if (((db->dbp)->cursor)(db->dbp, NULL, &temp_cursor) != 0)
9d9477b1 446#else
2c2d71f5 447 if (((db->dbp)->cursor)(db->dbp, NULL, &temp_cursor, 0) != 0)
9d9477b1 448#endif
2c2d71f5 449 return (-1) ;
450
451 memset(&l_key, 0, sizeof(l_key));
452 l_key.data = key.data;
453 l_key.size = key.size;
454 memset(&l_value, 0, sizeof(l_value));
455 l_value.data = value.data;
456 l_value.size = value.size;
457
458 if ( temp_cursor->c_get(temp_cursor, &l_key, &l_value, DB_SET) != 0) {
459 (void)temp_cursor->c_close(temp_cursor);
460 return (-1);
461 }
462
463 status = temp_cursor->c_put(temp_cursor, &key, &value, flags);
464 (void)temp_cursor->c_close(temp_cursor);
465
466 return (status) ;
467 }
468
469
470 if (flagSet(flags, R_CURSOR)) {
471 return ((db->cursor)->c_put)(db->cursor, &key, &value, DB_CURRENT);
472 }
9d9477b1 473
2c2d71f5 474 if (flagSet(flags, R_SETCURSOR)) {
475 if ((db->dbp)->put(db->dbp, NULL, &key, &value, 0) != 0)
476 return -1 ;
477 return ((db->cursor)->c_get)(db->cursor, &key, &value, DB_SET_RANGE);
478
1f70e1ea 479 }
480
481 return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;
482
483}
484
485#endif /* DB_VERSION_MAJOR */
486
a0d0e21e 487
488static int
73969f8f 489#ifdef AT_LEAST_DB_3_2
490
491#ifdef CAN_PROTOTYPE
492btree_compare(DB * db, const DBT *key1, const DBT *key2)
493#else
494btree_compare(db, key1, key2)
495DB * db ;
496const DBT * key1 ;
497const DBT * key2 ;
498#endif /* CAN_PROTOTYPE */
499
500#else /* Berkeley DB < 3.2 */
501
2c2d71f5 502#ifdef CAN_PROTOTYPE
b76802f5 503btree_compare(const DBT *key1, const DBT *key2)
2c2d71f5 504#else
505btree_compare(key1, key2)
506const DBT * key1 ;
507const DBT * key2 ;
508#endif
73969f8f 509
510#endif
511
a0d0e21e 512{
2c2d71f5 513#ifdef dTHX
b76802f5 514 dTHX;
2c2d71f5 515#endif
a0d0e21e 516 dSP ;
df3728a2 517 dMY_CXT ;
518 void * data1, * data2 ;
a0d0e21e 519 int retval ;
520 int count ;
521
c5da4faf 522 data1 = (char *) key1->data ;
523 data2 = (char *) key2->data ;
cad2e5aa 524
2c2d71f5 525#ifndef newSVpvn
a0d0e21e 526 /* As newSVpv will assume that the data pointer is a null terminated C
527 string if the size parameter is 0, make sure that data points to an
528 empty string if the length is 0
529 */
530 if (key1->size == 0)
531 data1 = "" ;
532 if (key2->size == 0)
533 data2 = "" ;
2c2d71f5 534#endif
cad2e5aa 535
a0d0e21e 536 ENTER ;
537 SAVETMPS;
538
924508f0 539 PUSHMARK(SP) ;
540 EXTEND(SP,2) ;
2c2d71f5 541 PUSHs(sv_2mortal(newSVpvn(data1,key1->size)));
542 PUSHs(sv_2mortal(newSVpvn(data2,key2->size)));
a0d0e21e 543 PUTBACK ;
544
8e07c86e 545 count = perl_call_sv(CurrentDB->compare, G_SCALAR);
a0d0e21e 546
547 SPAGAIN ;
548
549 if (count != 1)
ff0cee69 550 croak ("DB_File btree_compare: expected 1 return value from compare sub, got %d\n", count) ;
a0d0e21e 551
552 retval = POPi ;
553
554 PUTBACK ;
555 FREETMPS ;
556 LEAVE ;
557 return (retval) ;
558
559}
560
ecfc5424 561static DB_Prefix_t
73969f8f 562#ifdef AT_LEAST_DB_3_2
563
564#ifdef CAN_PROTOTYPE
565btree_prefix(DB * db, const DBT *key1, const DBT *key2)
566#else
567btree_prefix(db, key1, key2)
568Db * db ;
569const DBT * key1 ;
570const DBT * key2 ;
571#endif
572
573#else /* Berkeley DB < 3.2 */
574
2c2d71f5 575#ifdef CAN_PROTOTYPE
b76802f5 576btree_prefix(const DBT *key1, const DBT *key2)
2c2d71f5 577#else
578btree_prefix(key1, key2)
579const DBT * key1 ;
580const DBT * key2 ;
581#endif
73969f8f 582
583#endif
a0d0e21e 584{
2c2d71f5 585#ifdef dTHX
b76802f5 586 dTHX;
2c2d71f5 587#endif
a0d0e21e 588 dSP ;
df3728a2 589 dMY_CXT ;
c5da4faf 590 char * data1, * data2 ;
a0d0e21e 591 int retval ;
592 int count ;
593
c5da4faf 594 data1 = (char *) key1->data ;
595 data2 = (char *) key2->data ;
cad2e5aa 596
2c2d71f5 597#ifndef newSVpvn
a0d0e21e 598 /* As newSVpv will assume that the data pointer is a null terminated C
599 string if the size parameter is 0, make sure that data points to an
600 empty string if the length is 0
601 */
602 if (key1->size == 0)
603 data1 = "" ;
604 if (key2->size == 0)
605 data2 = "" ;
2c2d71f5 606#endif
cad2e5aa 607
a0d0e21e 608 ENTER ;
609 SAVETMPS;
610
924508f0 611 PUSHMARK(SP) ;
612 EXTEND(SP,2) ;
2c2d71f5 613 PUSHs(sv_2mortal(newSVpvn(data1,key1->size)));
614 PUSHs(sv_2mortal(newSVpvn(data2,key2->size)));
a0d0e21e 615 PUTBACK ;
616
8e07c86e 617 count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
a0d0e21e 618
619 SPAGAIN ;
620
621 if (count != 1)
ff0cee69 622 croak ("DB_File btree_prefix: expected 1 return value from prefix sub, got %d\n", count) ;
a0d0e21e 623
624 retval = POPi ;
625
626 PUTBACK ;
627 FREETMPS ;
628 LEAVE ;
629
630 return (retval) ;
631}
632
3245f058 633
73969f8f 634#ifdef BERKELEY_DB_1
a56128cb 635# define HASH_CB_SIZE_TYPE size_t
636#else
637# define HASH_CB_SIZE_TYPE u_int32_t
638#endif
639
ecfc5424 640static DB_Hash_t
73969f8f 641#ifdef AT_LEAST_DB_3_2
642
643#ifdef CAN_PROTOTYPE
644hash_cb(DB * db, const void *data, u_int32_t size)
645#else
646hash_cb(db, data, size)
647DB * db ;
648const void * data ;
649HASH_CB_SIZE_TYPE size ;
650#endif
651
652#else /* Berkeley DB < 3.2 */
653
2c2d71f5 654#ifdef CAN_PROTOTYPE
a56128cb 655hash_cb(const void *data, HASH_CB_SIZE_TYPE size)
2c2d71f5 656#else
657hash_cb(data, size)
658const void * data ;
a56128cb 659HASH_CB_SIZE_TYPE size ;
2c2d71f5 660#endif
73969f8f 661
662#endif
a0d0e21e 663{
2c2d71f5 664#ifdef dTHX
b76802f5 665 dTHX;
2c2d71f5 666#endif
a0d0e21e 667 dSP ;
df3728a2 668 dMY_CXT;
a0d0e21e 669 int retval ;
670 int count ;
cad2e5aa 671
2c2d71f5 672#ifndef newSVpvn
a0d0e21e 673 if (size == 0)
674 data = "" ;
2c2d71f5 675#endif
cad2e5aa 676
610ab055 677 /* DGH - Next two lines added to fix corrupted stack problem */
678 ENTER ;
679 SAVETMPS;
680
924508f0 681 PUSHMARK(SP) ;
610ab055 682
2c2d71f5 683 XPUSHs(sv_2mortal(newSVpvn((char*)data,size)));
a0d0e21e 684 PUTBACK ;
685
8e07c86e 686 count = perl_call_sv(CurrentDB->hash, G_SCALAR);
a0d0e21e 687
688 SPAGAIN ;
689
690 if (count != 1)
ff0cee69 691 croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ;
a0d0e21e 692
693 retval = POPi ;
694
695 PUTBACK ;
696 FREETMPS ;
697 LEAVE ;
698
699 return (retval) ;
700}
701
702
ccb44e3b 703#if defined(TRACE) && defined(BERKELEY_DB_1_OR_2)
a0d0e21e 704
705static void
2c2d71f5 706#ifdef CAN_PROTOTYPE
b76802f5 707PrintHash(INFO *hash)
2c2d71f5 708#else
709PrintHash(hash)
710INFO * hash ;
711#endif
a0d0e21e 712{
713 printf ("HASH Info\n") ;
1f70e1ea 714 printf (" hash = %s\n",
715 (hash->db_HA_hash != NULL ? "redefined" : "default")) ;
716 printf (" bsize = %d\n", hash->db_HA_bsize) ;
717 printf (" ffactor = %d\n", hash->db_HA_ffactor) ;
718 printf (" nelem = %d\n", hash->db_HA_nelem) ;
719 printf (" cachesize = %d\n", hash->db_HA_cachesize) ;
720 printf (" lorder = %d\n", hash->db_HA_lorder) ;
a0d0e21e 721
722}
723
724static void
2c2d71f5 725#ifdef CAN_PROTOTYPE
b76802f5 726PrintRecno(INFO *recno)
2c2d71f5 727#else
728PrintRecno(recno)
729INFO * recno ;
730#endif
a0d0e21e 731{
732 printf ("RECNO Info\n") ;
1f70e1ea 733 printf (" flags = %d\n", recno->db_RE_flags) ;
734 printf (" cachesize = %d\n", recno->db_RE_cachesize) ;
735 printf (" psize = %d\n", recno->db_RE_psize) ;
736 printf (" lorder = %d\n", recno->db_RE_lorder) ;
737 printf (" reclen = %ul\n", (unsigned long)recno->db_RE_reclen) ;
738 printf (" bval = %d 0x%x\n", recno->db_RE_bval, recno->db_RE_bval) ;
739 printf (" bfname = %d [%s]\n", recno->db_RE_bfname, recno->db_RE_bfname) ;
a0d0e21e 740}
741
ff68c719 742static void
2c2d71f5 743#ifdef CAN_PROTOTYPE
b76802f5 744PrintBtree(INFO *btree)
2c2d71f5 745#else
746PrintBtree(btree)
747INFO * btree ;
748#endif
a0d0e21e 749{
750 printf ("BTREE Info\n") ;
1f70e1ea 751 printf (" compare = %s\n",
752 (btree->db_BT_compare ? "redefined" : "default")) ;
753 printf (" prefix = %s\n",
754 (btree->db_BT_prefix ? "redefined" : "default")) ;
755 printf (" flags = %d\n", btree->db_BT_flags) ;
756 printf (" cachesize = %d\n", btree->db_BT_cachesize) ;
757 printf (" psize = %d\n", btree->db_BT_psize) ;
758#ifndef DB_VERSION_MAJOR
759 printf (" maxkeypage = %d\n", btree->db_BT_maxkeypage) ;
760 printf (" minkeypage = %d\n", btree->db_BT_minkeypage) ;
761#endif
762 printf (" lorder = %d\n", btree->db_BT_lorder) ;
a0d0e21e 763}
764
765#else
766
767#define PrintRecno(recno)
768#define PrintHash(hash)
769#define PrintBtree(btree)
770
771#endif /* TRACE */
772
773
774static I32
2c2d71f5 775#ifdef CAN_PROTOTYPE
b76802f5 776GetArrayLength(pTHX_ DB_File db)
2c2d71f5 777#else
778GetArrayLength(db)
779DB_File db ;
780#endif
a0d0e21e 781{
782 DBT key ;
783 DBT value ;
784 int RETVAL ;
785
ccb44e3b 786 DBT_clear(key) ;
787 DBT_clear(value) ;
1f70e1ea 788 RETVAL = do_SEQ(db, key, value, R_LAST) ;
a0d0e21e 789 if (RETVAL == 0)
790 RETVAL = *(I32 *)key.data ;
1f70e1ea 791 else /* No key means empty file */
a0d0e21e 792 RETVAL = 0 ;
793
a0b8c8c1 794 return ((I32)RETVAL) ;
a0d0e21e 795}
796
88108326 797static recno_t
2c2d71f5 798#ifdef CAN_PROTOTYPE
b76802f5 799GetRecnoKey(pTHX_ DB_File db, I32 value)
2c2d71f5 800#else
801GetRecnoKey(db, value)
802DB_File db ;
803I32 value ;
804#endif
88108326 805{
806 if (value < 0) {
807 /* Get the length of the array */
b76802f5 808 I32 length = GetArrayLength(aTHX_ db) ;
88108326 809
810 /* check for attempt to write before start of array */
811 if (length + value + 1 <= 0)
ff0cee69 812 croak("Modification of non-creatable array value attempted, subscript %ld", (long)value) ;
88108326 813
814 value = length + value + 1 ;
815 }
816 else
817 ++ value ;
818
819 return value ;
a0d0e21e 820}
821
ccb44e3b 822
a0d0e21e 823static DB_File
2c2d71f5 824#ifdef CAN_PROTOTYPE
b76802f5 825ParseOpenInfo(pTHX_ int isHASH, char *name, int flags, int mode, SV *sv)
2c2d71f5 826#else
827ParseOpenInfo(isHASH, name, flags, mode, sv)
828int isHASH ;
829char * name ;
830int flags ;
831int mode ;
832SV * sv ;
833#endif
a0d0e21e 834{
ccb44e3b 835
836#ifdef BERKELEY_DB_1_OR_2 /* Berkeley DB Version 1 or 2 */
837
a0d0e21e 838 SV ** svp;
839 HV * action ;
045291aa 840 DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ;
a0d0e21e 841 void * openinfo = NULL ;
045291aa 842 INFO * info = &RETVAL->info ;
2d8e6c8d 843 STRLEN n_a;
df3728a2 844 dMY_CXT;
1f70e1ea 845
846/* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
045291aa 847 Zero(RETVAL, 1, DB_File_type) ;
a0d0e21e 848
88108326 849 /* Default to HASH */
9fe6733a 850 RETVAL->filtering = 0 ;
851 RETVAL->filter_fetch_key = RETVAL->filter_store_key =
852 RETVAL->filter_fetch_value = RETVAL->filter_store_value =
8e07c86e 853 RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
854 RETVAL->type = DB_HASH ;
a0d0e21e 855
610ab055 856 /* DGH - Next line added to avoid SEGV on existing hash DB */
857 CurrentDB = RETVAL;
858
a0b8c8c1 859 /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */
860 RETVAL->in_memory = (name == NULL) ;
861
a0d0e21e 862 if (sv)
863 {
864 if (! SvROK(sv) )
865 croak ("type parameter is not a reference") ;
866
36477c24 867 svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ;
868 if (svp && SvOK(*svp))
869 action = (HV*) SvRV(*svp) ;
870 else
871 croak("internal error") ;
610ab055 872
a0d0e21e 873 if (sv_isa(sv, "DB_File::HASHINFO"))
874 {
05475680 875
876 if (!isHASH)
877 croak("DB_File can only tie an associative array to a DB_HASH database") ;
878
8e07c86e 879 RETVAL->type = DB_HASH ;
610ab055 880 openinfo = (void*)info ;
a0d0e21e 881
882 svp = hv_fetch(action, "hash", 4, FALSE);
883
884 if (svp && SvOK(*svp))
885 {
1f70e1ea 886 info->db_HA_hash = hash_cb ;
8e07c86e 887 RETVAL->hash = newSVsv(*svp) ;
a0d0e21e 888 }
889 else
1f70e1ea 890 info->db_HA_hash = NULL ;
a0d0e21e 891
a0d0e21e 892 svp = hv_fetch(action, "ffactor", 7, FALSE);
1f70e1ea 893 info->db_HA_ffactor = svp ? SvIV(*svp) : 0;
a0d0e21e 894
895 svp = hv_fetch(action, "nelem", 5, FALSE);
1f70e1ea 896 info->db_HA_nelem = svp ? SvIV(*svp) : 0;
a0d0e21e 897
1f70e1ea 898 svp = hv_fetch(action, "bsize", 5, FALSE);
899 info->db_HA_bsize = svp ? SvIV(*svp) : 0;
900
a0d0e21e 901 svp = hv_fetch(action, "cachesize", 9, FALSE);
1f70e1ea 902 info->db_HA_cachesize = svp ? SvIV(*svp) : 0;
a0d0e21e 903
904 svp = hv_fetch(action, "lorder", 6, FALSE);
1f70e1ea 905 info->db_HA_lorder = svp ? SvIV(*svp) : 0;
a0d0e21e 906
907 PrintHash(info) ;
908 }
909 else if (sv_isa(sv, "DB_File::BTREEINFO"))
910 {
05475680 911 if (!isHASH)
912 croak("DB_File can only tie an associative array to a DB_BTREE database");
913
8e07c86e 914 RETVAL->type = DB_BTREE ;
610ab055 915 openinfo = (void*)info ;
a0d0e21e 916
917 svp = hv_fetch(action, "compare", 7, FALSE);
918 if (svp && SvOK(*svp))
919 {
1f70e1ea 920 info->db_BT_compare = btree_compare ;
8e07c86e 921 RETVAL->compare = newSVsv(*svp) ;
a0d0e21e 922 }
923 else
1f70e1ea 924 info->db_BT_compare = NULL ;
a0d0e21e 925
926 svp = hv_fetch(action, "prefix", 6, FALSE);
927 if (svp && SvOK(*svp))
928 {
1f70e1ea 929 info->db_BT_prefix = btree_prefix ;
8e07c86e 930 RETVAL->prefix = newSVsv(*svp) ;
a0d0e21e 931 }
932 else
1f70e1ea 933 info->db_BT_prefix = NULL ;
a0d0e21e 934
935 svp = hv_fetch(action, "flags", 5, FALSE);
1f70e1ea 936 info->db_BT_flags = svp ? SvIV(*svp) : 0;
a0d0e21e 937
938 svp = hv_fetch(action, "cachesize", 9, FALSE);
1f70e1ea 939 info->db_BT_cachesize = svp ? SvIV(*svp) : 0;
a0d0e21e 940
1f70e1ea 941#ifndef DB_VERSION_MAJOR
a0d0e21e 942 svp = hv_fetch(action, "minkeypage", 10, FALSE);
610ab055 943 info->btree.minkeypage = svp ? SvIV(*svp) : 0;
a0d0e21e 944
945 svp = hv_fetch(action, "maxkeypage", 10, FALSE);
610ab055 946 info->btree.maxkeypage = svp ? SvIV(*svp) : 0;
1f70e1ea 947#endif
a0d0e21e 948
949 svp = hv_fetch(action, "psize", 5, FALSE);
1f70e1ea 950 info->db_BT_psize = svp ? SvIV(*svp) : 0;
a0d0e21e 951
952 svp = hv_fetch(action, "lorder", 6, FALSE);
1f70e1ea 953 info->db_BT_lorder = svp ? SvIV(*svp) : 0;
a0d0e21e 954
955 PrintBtree(info) ;
956
957 }
958 else if (sv_isa(sv, "DB_File::RECNOINFO"))
959 {
05475680 960 if (isHASH)
961 croak("DB_File can only tie an array to a DB_RECNO database");
962
8e07c86e 963 RETVAL->type = DB_RECNO ;
610ab055 964 openinfo = (void *)info ;
a0d0e21e 965
1f70e1ea 966 info->db_RE_flags = 0 ;
967
a0d0e21e 968 svp = hv_fetch(action, "flags", 5, FALSE);
1f70e1ea 969 info->db_RE_flags = (u_long) (svp ? SvIV(*svp) : 0);
970
971 svp = hv_fetch(action, "reclen", 6, FALSE);
972 info->db_RE_reclen = (size_t) (svp ? SvIV(*svp) : 0);
a0d0e21e 973
974 svp = hv_fetch(action, "cachesize", 9, FALSE);
1f70e1ea 975 info->db_RE_cachesize = (u_int) (svp ? SvIV(*svp) : 0);
a0d0e21e 976
977 svp = hv_fetch(action, "psize", 5, FALSE);
1f70e1ea 978 info->db_RE_psize = (u_int) (svp ? SvIV(*svp) : 0);
a0d0e21e 979
980 svp = hv_fetch(action, "lorder", 6, FALSE);
1f70e1ea 981 info->db_RE_lorder = (int) (svp ? SvIV(*svp) : 0);
982
983#ifdef DB_VERSION_MAJOR
984 info->re_source = name ;
985 name = NULL ;
986#endif
987 svp = hv_fetch(action, "bfname", 6, FALSE);
988 if (svp && SvOK(*svp)) {
2d8e6c8d 989 char * ptr = SvPV(*svp,n_a) ;
1f70e1ea 990#ifdef DB_VERSION_MAJOR
2d8e6c8d 991 name = (char*) n_a ? ptr : NULL ;
1f70e1ea 992#else
2d8e6c8d 993 info->db_RE_bfname = (char*) (n_a ? ptr : NULL) ;
1f70e1ea 994#endif
995 }
996 else
997#ifdef DB_VERSION_MAJOR
998 name = NULL ;
999#else
1000 info->db_RE_bfname = NULL ;
1001#endif
a0d0e21e 1002
1003 svp = hv_fetch(action, "bval", 4, FALSE);
1f70e1ea 1004#ifdef DB_VERSION_MAJOR
a0d0e21e 1005 if (svp && SvOK(*svp))
1006 {
1f70e1ea 1007 int value ;
a0d0e21e 1008 if (SvPOK(*svp))
2d8e6c8d 1009 value = (int)*SvPV(*svp, n_a) ;
a0d0e21e 1010 else
1f70e1ea 1011 value = SvIV(*svp) ;
1012
1013 if (info->flags & DB_FIXEDLEN) {
1014 info->re_pad = value ;
1015 info->flags |= DB_PAD ;
1016 }
1017 else {
1018 info->re_delim = value ;
1019 info->flags |= DB_DELIMITER ;
1020 }
1021
1022 }
1023#else
1024 if (svp && SvOK(*svp))
1025 {
1026 if (SvPOK(*svp))
2d8e6c8d 1027 info->db_RE_bval = (u_char)*SvPV(*svp, n_a) ;
1f70e1ea 1028 else
1029 info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ;
1030 DB_flags(info->flags, DB_DELIMITER) ;
1031
a0d0e21e 1032 }
1033 else
1034 {
1f70e1ea 1035 if (info->db_RE_flags & R_FIXEDLEN)
1036 info->db_RE_bval = (u_char) ' ' ;
a0d0e21e 1037 else
1f70e1ea 1038 info->db_RE_bval = (u_char) '\n' ;
1039 DB_flags(info->flags, DB_DELIMITER) ;
a0d0e21e 1040 }
1f70e1ea 1041#endif
a0d0e21e 1042
1f70e1ea 1043#ifdef DB_RENUMBER
1044 info->flags |= DB_RENUMBER ;
1045#endif
1046
a0d0e21e 1047 PrintRecno(info) ;
1048 }
1049 else
1050 croak("type is not of type DB_File::HASHINFO, DB_File::BTREEINFO or DB_File::RECNOINFO");
1051 }
1052
1053
88108326 1054 /* OS2 Specific Code */
1055#ifdef OS2
1056#ifdef __EMX__
1057 flags |= O_BINARY;
1058#endif /* __EMX__ */
1059#endif /* OS2 */
a0d0e21e 1060
1f70e1ea 1061#ifdef DB_VERSION_MAJOR
1062
1063 {
1064 int Flags = 0 ;
1065 int status ;
1066
1067 /* Map 1.x flags to 2.x flags */
1068 if ((flags & O_CREAT) == O_CREAT)
1069 Flags |= DB_CREATE ;
1070
1f70e1ea 1071#if O_RDONLY == 0
1072 if (flags == O_RDONLY)
1073#else
20896112 1074 if ((flags & O_RDONLY) == O_RDONLY && (flags & O_RDWR) != O_RDWR)
1f70e1ea 1075#endif
1076 Flags |= DB_RDONLY ;
1077
20896112 1078#ifdef O_TRUNC
1f70e1ea 1079 if ((flags & O_TRUNC) == O_TRUNC)
1080 Flags |= DB_TRUNCATE ;
1081#endif
1082
1083 status = db_open(name, RETVAL->type, Flags, mode, NULL, openinfo, &RETVAL->dbp) ;
1084 if (status == 0)
6ca2e664 1085#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
1f70e1ea 1086 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor) ;
6ca2e664 1087#else
1088 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor,
1089 0) ;
1090#endif
1f70e1ea 1091
1092 if (status)
1093 RETVAL->dbp = NULL ;
1094
1095 }
1096#else
ccb44e3b 1097
1098#if defined(DB_LIBRARY_COMPATIBILITY_API) && DB_VERSION_MAJOR > 2
1099 RETVAL->dbp = __db185_open(name, flags, mode, RETVAL->type, openinfo) ;
1100#else
88108326 1101 RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ;
ccb44e3b 1102#endif /* DB_LIBRARY_COMPATIBILITY_API */
1103
1f70e1ea 1104#endif
a0d0e21e 1105
1106 return (RETVAL) ;
ccb44e3b 1107
1108#else /* Berkeley DB Version > 2 */
1109
1110 SV ** svp;
1111 HV * action ;
1112 DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ;
1113 DB * dbp ;
1114 STRLEN n_a;
1115 int status ;
df3728a2 1116 dMY_CXT;
ccb44e3b 1117
1118/* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
1119 Zero(RETVAL, 1, DB_File_type) ;
1120
1121 /* Default to HASH */
ccb44e3b 1122 RETVAL->filtering = 0 ;
1123 RETVAL->filter_fetch_key = RETVAL->filter_store_key =
1124 RETVAL->filter_fetch_value = RETVAL->filter_store_value =
ccb44e3b 1125 RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
1126 RETVAL->type = DB_HASH ;
1127
1128 /* DGH - Next line added to avoid SEGV on existing hash DB */
1129 CurrentDB = RETVAL;
1130
1131 /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */
1132 RETVAL->in_memory = (name == NULL) ;
1133
1134 status = db_create(&RETVAL->dbp, NULL,0) ;
1135 /* printf("db_create returned %d %s\n", status, db_strerror(status)) ; */
1136 if (status) {
1137 RETVAL->dbp = NULL ;
1138 return (RETVAL) ;
1139 }
1140 dbp = RETVAL->dbp ;
1141
1142 if (sv)
1143 {
1144 if (! SvROK(sv) )
1145 croak ("type parameter is not a reference") ;
1146
1147 svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ;
1148 if (svp && SvOK(*svp))
1149 action = (HV*) SvRV(*svp) ;
1150 else
1151 croak("internal error") ;
1152
1153 if (sv_isa(sv, "DB_File::HASHINFO"))
1154 {
1155
1156 if (!isHASH)
1157 croak("DB_File can only tie an associative array to a DB_HASH database") ;
1158
1159 RETVAL->type = DB_HASH ;
1160
1161 svp = hv_fetch(action, "hash", 4, FALSE);
1162
1163 if (svp && SvOK(*svp))
1164 {
1165 (void)dbp->set_h_hash(dbp, hash_cb) ;
1166 RETVAL->hash = newSVsv(*svp) ;
1167 }
1168
1169 svp = hv_fetch(action, "ffactor", 7, FALSE);
1170 if (svp)
c6c92ad9 1171 (void)dbp->set_h_ffactor(dbp, my_SvUV32(*svp)) ;
ccb44e3b 1172
1173 svp = hv_fetch(action, "nelem", 5, FALSE);
1174 if (svp)
c6c92ad9 1175 (void)dbp->set_h_nelem(dbp, my_SvUV32(*svp)) ;
ccb44e3b 1176
1177 svp = hv_fetch(action, "bsize", 5, FALSE);
1178 if (svp)
c6c92ad9 1179 (void)dbp->set_pagesize(dbp, my_SvUV32(*svp));
ccb44e3b 1180
1181 svp = hv_fetch(action, "cachesize", 9, FALSE);
1182 if (svp)
c6c92ad9 1183 (void)dbp->set_cachesize(dbp, 0, my_SvUV32(*svp), 0) ;
ccb44e3b 1184
1185 svp = hv_fetch(action, "lorder", 6, FALSE);
1186 if (svp)
c6c92ad9 1187 (void)dbp->set_lorder(dbp, (int)SvIV(*svp)) ;
ccb44e3b 1188
1189 PrintHash(info) ;
1190 }
1191 else if (sv_isa(sv, "DB_File::BTREEINFO"))
1192 {
1193 if (!isHASH)
1194 croak("DB_File can only tie an associative array to a DB_BTREE database");
1195
1196 RETVAL->type = DB_BTREE ;
1197
1198 svp = hv_fetch(action, "compare", 7, FALSE);
1199 if (svp && SvOK(*svp))
1200 {
1201 (void)dbp->set_bt_compare(dbp, btree_compare) ;
1202 RETVAL->compare = newSVsv(*svp) ;
1203 }
1204
1205 svp = hv_fetch(action, "prefix", 6, FALSE);
1206 if (svp && SvOK(*svp))
1207 {
1208 (void)dbp->set_bt_prefix(dbp, btree_prefix) ;
1209 RETVAL->prefix = newSVsv(*svp) ;
1210 }
1211
1212 svp = hv_fetch(action, "flags", 5, FALSE);
1213 if (svp)
c6c92ad9 1214 (void)dbp->set_flags(dbp, my_SvUV32(*svp)) ;
ccb44e3b 1215
1216 svp = hv_fetch(action, "cachesize", 9, FALSE);
1217 if (svp)
c6c92ad9 1218 (void)dbp->set_cachesize(dbp, 0, my_SvUV32(*svp), 0) ;
ccb44e3b 1219
1220 svp = hv_fetch(action, "psize", 5, FALSE);
1221 if (svp)
c6c92ad9 1222 (void)dbp->set_pagesize(dbp, my_SvUV32(*svp)) ;
ccb44e3b 1223
1224 svp = hv_fetch(action, "lorder", 6, FALSE);
1225 if (svp)
c6c92ad9 1226 (void)dbp->set_lorder(dbp, (int)SvIV(*svp)) ;
ccb44e3b 1227
1228 PrintBtree(info) ;
1229
1230 }
1231 else if (sv_isa(sv, "DB_File::RECNOINFO"))
1232 {
1233 int fixed = FALSE ;
1234
1235 if (isHASH)
1236 croak("DB_File can only tie an array to a DB_RECNO database");
1237
1238 RETVAL->type = DB_RECNO ;
1239
1240 svp = hv_fetch(action, "flags", 5, FALSE);
1241 if (svp) {
1242 int flags = SvIV(*svp) ;
1243 /* remove FIXDLEN, if present */
1244 if (flags & DB_FIXEDLEN) {
1245 fixed = TRUE ;
1246 flags &= ~DB_FIXEDLEN ;
1247 }
1248 }
1249
1250 svp = hv_fetch(action, "cachesize", 9, FALSE);
1251 if (svp) {
c6c92ad9 1252 status = dbp->set_cachesize(dbp, 0, my_SvUV32(*svp), 0) ;
ccb44e3b 1253 }
1254
1255 svp = hv_fetch(action, "psize", 5, FALSE);
1256 if (svp) {
c6c92ad9 1257 status = dbp->set_pagesize(dbp, my_SvUV32(*svp)) ;
ccb44e3b 1258 }
1259
1260 svp = hv_fetch(action, "lorder", 6, FALSE);
1261 if (svp) {
c6c92ad9 1262 status = dbp->set_lorder(dbp, (int)SvIV(*svp)) ;
ccb44e3b 1263 }
1264
1265 svp = hv_fetch(action, "bval", 4, FALSE);
1266 if (svp && SvOK(*svp))
1267 {
1268 int value ;
1269 if (SvPOK(*svp))
1270 value = (int)*SvPV(*svp, n_a) ;
1271 else
c6c92ad9 1272 value = (int)SvIV(*svp) ;
ccb44e3b 1273
1274 if (fixed) {
1275 status = dbp->set_re_pad(dbp, value) ;
1276 }
1277 else {
1278 status = dbp->set_re_delim(dbp, value) ;
1279 }
1280
1281 }
1282
1283 if (fixed) {
1284 svp = hv_fetch(action, "reclen", 6, FALSE);
1285 if (svp) {
c6c92ad9 1286 u_int32_t len = my_SvUV32(*svp) ;
ccb44e3b 1287 status = dbp->set_re_len(dbp, len) ;
1288 }
1289 }
1290
1291 if (name != NULL) {
1292 status = dbp->set_re_source(dbp, name) ;
1293 name = NULL ;
1294 }
1295
1296 svp = hv_fetch(action, "bfname", 6, FALSE);
1297 if (svp && SvOK(*svp)) {
1298 char * ptr = SvPV(*svp,n_a) ;
1299 name = (char*) n_a ? ptr : NULL ;
1300 }
1301 else
1302 name = NULL ;
1303
1304
c6c92ad9 1305 status = dbp->set_flags(dbp, (u_int32_t)DB_RENUMBER) ;
ccb44e3b 1306
1307 if (flags){
c6c92ad9 1308 (void)dbp->set_flags(dbp, (u_int32_t)flags) ;
ccb44e3b 1309 }
1310 PrintRecno(info) ;
1311 }
1312 else
1313 croak("type is not of type DB_File::HASHINFO, DB_File::BTREEINFO or DB_File::RECNOINFO");
1314 }
1315
1316 {
c6c92ad9 1317 u_int32_t Flags = 0 ;
ccb44e3b 1318 int status ;
1319
1320 /* Map 1.x flags to 3.x flags */
1321 if ((flags & O_CREAT) == O_CREAT)
1322 Flags |= DB_CREATE ;
1323
1324#if O_RDONLY == 0
1325 if (flags == O_RDONLY)
1326#else
1327 if ((flags & O_RDONLY) == O_RDONLY && (flags & O_RDWR) != O_RDWR)
1328#endif
1329 Flags |= DB_RDONLY ;
1330
1331#ifdef O_TRUNC
1332 if ((flags & O_TRUNC) == O_TRUNC)
1333 Flags |= DB_TRUNCATE ;
1334#endif
1335
3245f058 1336 status = (RETVAL->dbp->open)(RETVAL->dbp, name, NULL, RETVAL->type,
ccb44e3b 1337 Flags, mode) ;
1338 /* printf("open returned %d %s\n", status, db_strerror(status)) ; */
1339
1340 if (status == 0)
1341 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor,
1342 0) ;
1343 /* printf("cursor returned %d %s\n", status, db_strerror(status)) ; */
1344
1345 if (status)
1346 RETVAL->dbp = NULL ;
1347
1348 }
1349
1350 return (RETVAL) ;
1351
1352#endif /* Berkeley DB Version > 2 */
1353
1354} /* ParseOpenInfo */
a0d0e21e 1355
1356
07200f1b 1357#include "constants.h"
a0d0e21e 1358
1359MODULE = DB_File PACKAGE = DB_File PREFIX = db_
1360
07200f1b 1361INCLUDE: constants.xs
1362
1f70e1ea 1363BOOT:
1364 {
df3728a2 1365 MY_CXT_INIT;
ccb44e3b 1366 __getBerkeleyDBInfo() ;
1f70e1ea 1367
ccb44e3b 1368 DBT_clear(empty) ;
1f70e1ea 1369 empty.data = &zero ;
1370 empty.size = sizeof(recno_t) ;
1f70e1ea 1371 }
1372
a0d0e21e 1373
1374
1375DB_File
05475680 1376db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_HASH)
1377 int isHASH
a0d0e21e 1378 char * dbtype
1379 int flags
1380 int mode
1381 CODE:
1382 {
1383 char * name = (char *) NULL ;
1384 SV * sv = (SV *) NULL ;
2d8e6c8d 1385 STRLEN n_a;
a0d0e21e 1386
05475680 1387 if (items >= 3 && SvOK(ST(2)))
2d8e6c8d 1388 name = (char*) SvPV(ST(2), n_a) ;
a0d0e21e 1389
05475680 1390 if (items == 6)
1391 sv = ST(5) ;
a0d0e21e 1392
b76802f5 1393 RETVAL = ParseOpenInfo(aTHX_ isHASH, name, flags, mode, sv) ;
4633a7c4 1394 if (RETVAL->dbp == NULL)
1395 RETVAL = NULL ;
a0d0e21e 1396 }
1397 OUTPUT:
1398 RETVAL
1399
a0d0e21e 1400int
1401db_DESTROY(db)
1402 DB_File db
df3728a2 1403 PREINIT:
1404 dMY_CXT;
8e07c86e 1405 INIT:
1406 CurrentDB = db ;
1407 CLEANUP:
1408 if (db->hash)
1409 SvREFCNT_dec(db->hash) ;
1410 if (db->compare)
1411 SvREFCNT_dec(db->compare) ;
1412 if (db->prefix)
1413 SvREFCNT_dec(db->prefix) ;
9fe6733a 1414 if (db->filter_fetch_key)
1415 SvREFCNT_dec(db->filter_fetch_key) ;
1416 if (db->filter_store_key)
1417 SvREFCNT_dec(db->filter_store_key) ;
1418 if (db->filter_fetch_value)
1419 SvREFCNT_dec(db->filter_fetch_value) ;
1420 if (db->filter_store_value)
1421 SvREFCNT_dec(db->filter_store_value) ;
eb99164f 1422 safefree(db) ;
1f70e1ea 1423#ifdef DB_VERSION_MAJOR
1424 if (RETVAL > 0)
1425 RETVAL = -1 ;
1426#endif
a0d0e21e 1427
1428
1429int
1430db_DELETE(db, key, flags=0)
1431 DB_File db
1432 DBTKEY key
1433 u_int flags
df3728a2 1434 PREINIT:
1435 dMY_CXT;
8e07c86e 1436 INIT:
1437 CurrentDB = db ;
a0d0e21e 1438
f6b705ef 1439
1440int
1441db_EXISTS(db, key)
1442 DB_File db
1443 DBTKEY key
df3728a2 1444 PREINIT:
1445 dMY_CXT;
f6b705ef 1446 CODE:
1447 {
1448 DBT value ;
1449
ccb44e3b 1450 DBT_clear(value) ;
f6b705ef 1451 CurrentDB = db ;
1f70e1ea 1452 RETVAL = (((db->dbp)->get)(db->dbp, TXN &key, &value, 0) == 0) ;
f6b705ef 1453 }
1454 OUTPUT:
1455 RETVAL
1456
c6c619a9 1457void
a0d0e21e 1458db_FETCH(db, key, flags=0)
1459 DB_File db
1460 DBTKEY key
1461 u_int flags
c6c619a9 1462 PREINIT:
07200f1b 1463 dMY_CXT ;
1464 int RETVAL ;
a0d0e21e 1465 CODE:
1466 {
1f70e1ea 1467 DBT value ;
a0d0e21e 1468
ccb44e3b 1469 DBT_clear(value) ;
8e07c86e 1470 CurrentDB = db ;
1f70e1ea 1471 /* RETVAL = ((db->dbp)->get)(db->dbp, TXN &key, &value, flags) ; */
1472 RETVAL = db_get(db, key, value, flags) ;
a0d0e21e 1473 ST(0) = sv_newmortal();
a9fd575d 1474 OutputValue(ST(0), value)
a0d0e21e 1475 }
1476
1477int
1478db_STORE(db, key, value, flags=0)
1479 DB_File db
1480 DBTKEY key
1481 DBT value
1482 u_int flags
df3728a2 1483 PREINIT:
1484 dMY_CXT;
8e07c86e 1485 INIT:
1486 CurrentDB = db ;
a0d0e21e 1487
1488
c6c619a9 1489void
a0d0e21e 1490db_FIRSTKEY(db)
1491 DB_File db
c6c619a9 1492 PREINIT:
07200f1b 1493 dMY_CXT ;
1494 int RETVAL ;
a0d0e21e 1495 CODE:
1496 {
1f70e1ea 1497 DBTKEY key ;
a0d0e21e 1498 DBT value ;
1499
ccb44e3b 1500 DBT_clear(key) ;
1501 DBT_clear(value) ;
8e07c86e 1502 CurrentDB = db ;
1f70e1ea 1503 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
a0d0e21e 1504 ST(0) = sv_newmortal();
a9fd575d 1505 OutputKey(ST(0), key) ;
a0d0e21e 1506 }
1507
c6c619a9 1508void
a0d0e21e 1509db_NEXTKEY(db, key)
1510 DB_File db
0bf2e707 1511 DBTKEY key = NO_INIT
c6c619a9 1512 PREINIT:
07200f1b 1513 dMY_CXT ;
1514 int RETVAL ;
a0d0e21e 1515 CODE:
1516 {
1517 DBT value ;
1518
0bf2e707 1519 DBT_clear(key) ;
ccb44e3b 1520 DBT_clear(value) ;
8e07c86e 1521 CurrentDB = db ;
1f70e1ea 1522 RETVAL = do_SEQ(db, key, value, R_NEXT) ;
a0d0e21e 1523 ST(0) = sv_newmortal();
a9fd575d 1524 OutputKey(ST(0), key) ;
a0d0e21e 1525 }
1526
1527#
1528# These would be nice for RECNO
1529#
1530
1531int
1532unshift(db, ...)
1533 DB_File db
045291aa 1534 ALIAS: UNSHIFT = 1
df3728a2 1535 PREINIT:
1536 dMY_CXT;
a0d0e21e 1537 CODE:
1538 {
1539 DBTKEY key ;
1540 DBT value ;
1541 int i ;
1542 int One ;
2d8e6c8d 1543 STRLEN n_a;
a0d0e21e 1544
ccb44e3b 1545 DBT_clear(key) ;
1546 DBT_clear(value) ;
8e07c86e 1547 CurrentDB = db ;
1f70e1ea 1548#ifdef DB_VERSION_MAJOR
1549 /* get the first value */
1550 RETVAL = do_SEQ(db, key, value, DB_FIRST) ;
1551 RETVAL = 0 ;
1552#else
a0d0e21e 1553 RETVAL = -1 ;
1f70e1ea 1554#endif
a0d0e21e 1555 for (i = items-1 ; i > 0 ; --i)
1556 {
2d8e6c8d 1557 value.data = SvPV(ST(i), n_a) ;
1558 value.size = n_a ;
a0d0e21e 1559 One = 1 ;
1560 key.data = &One ;
1561 key.size = sizeof(int) ;
1f70e1ea 1562#ifdef DB_VERSION_MAJOR
1563 RETVAL = (db->cursor->c_put)(db->cursor, &key, &value, DB_BEFORE) ;
1564#else
b7953727 1565 RETVAL = (db->dbp->put)(db->dbp, &key, &value, R_IBEFORE) ;
1f70e1ea 1566#endif
a0d0e21e 1567 if (RETVAL != 0)
1568 break;
1569 }
1570 }
1571 OUTPUT:
1572 RETVAL
1573
c6c619a9 1574void
a0d0e21e 1575pop(db)
1576 DB_File db
df3728a2 1577 PREINIT:
1578 dMY_CXT;
045291aa 1579 ALIAS: POP = 1
c6c619a9 1580 PREINIT:
07200f1b 1581 I32 RETVAL;
a0d0e21e 1582 CODE:
1583 {
1584 DBTKEY key ;
1585 DBT value ;
1586
ccb44e3b 1587 DBT_clear(key) ;
1588 DBT_clear(value) ;
8e07c86e 1589 CurrentDB = db ;
1f70e1ea 1590
a0d0e21e 1591 /* First get the final value */
1f70e1ea 1592 RETVAL = do_SEQ(db, key, value, R_LAST) ;
a0d0e21e 1593 ST(0) = sv_newmortal();
1594 /* Now delete it */
1595 if (RETVAL == 0)
1596 {
f6b705ef 1597 /* the call to del will trash value, so take a copy now */
a9fd575d 1598 OutputValue(ST(0), value) ;
1f70e1ea 1599 RETVAL = db_del(db, key, R_CURSOR) ;
f6b705ef 1600 if (RETVAL != 0)
6b88bc9c 1601 sv_setsv(ST(0), &PL_sv_undef);
a0d0e21e 1602 }
1603 }
1604
c6c619a9 1605void
a0d0e21e 1606shift(db)
1607 DB_File db
df3728a2 1608 PREINIT:
1609 dMY_CXT;
045291aa 1610 ALIAS: SHIFT = 1
c6c619a9 1611 PREINIT:
07200f1b 1612 I32 RETVAL;
a0d0e21e 1613 CODE:
1614 {
a0d0e21e 1615 DBT value ;
f6b705ef 1616 DBTKEY key ;
a0d0e21e 1617
ccb44e3b 1618 DBT_clear(key) ;
1619 DBT_clear(value) ;
8e07c86e 1620 CurrentDB = db ;
a0d0e21e 1621 /* get the first value */
1f70e1ea 1622 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
a0d0e21e 1623 ST(0) = sv_newmortal();
1624 /* Now delete it */
1625 if (RETVAL == 0)
1626 {
f6b705ef 1627 /* the call to del will trash value, so take a copy now */
a9fd575d 1628 OutputValue(ST(0), value) ;
1f70e1ea 1629 RETVAL = db_del(db, key, R_CURSOR) ;
f6b705ef 1630 if (RETVAL != 0)
6b88bc9c 1631 sv_setsv (ST(0), &PL_sv_undef) ;
a0d0e21e 1632 }
1633 }
1634
1635
1636I32
1637push(db, ...)
1638 DB_File db
df3728a2 1639 PREINIT:
1640 dMY_CXT;
045291aa 1641 ALIAS: PUSH = 1
a0d0e21e 1642 CODE:
1643 {
1644 DBTKEY key ;
1645 DBT value ;
4633a7c4 1646 DB * Db = db->dbp ;
a0d0e21e 1647 int i ;
2d8e6c8d 1648 STRLEN n_a;
ccb44e3b 1649 int keyval ;
a0d0e21e 1650
1f70e1ea 1651 DBT_flags(key) ;
1652 DBT_flags(value) ;
8e07c86e 1653 CurrentDB = db ;
ca63f0d2 1654 /* Set the Cursor to the Last element */
1655 RETVAL = do_SEQ(db, key, value, R_LAST) ;
ccb44e3b 1656#ifndef DB_VERSION_MAJOR
ca63f0d2 1657 if (RETVAL >= 0)
ccb44e3b 1658#endif
ca63f0d2 1659 {
ccb44e3b 1660 if (RETVAL == 0)
1661 keyval = *(int*)key.data ;
1662 else
1663 keyval = 0 ;
1664 for (i = 1 ; i < items ; ++i)
8e07c86e 1665 {
2d8e6c8d 1666 value.data = SvPV(ST(i), n_a) ;
1667 value.size = n_a ;
ccb44e3b 1668 ++ keyval ;
1669 key.data = &keyval ;
1670 key.size = sizeof(int) ;
1671 RETVAL = (Db->put)(Db, TXN &key, &value, 0) ;
8e07c86e 1672 if (RETVAL != 0)
1673 break;
1674 }
a0d0e21e 1675 }
1676 }
1677 OUTPUT:
1678 RETVAL
1679
a0d0e21e 1680I32
1681length(db)
1682 DB_File db
df3728a2 1683 PREINIT:
1684 dMY_CXT;
045291aa 1685 ALIAS: FETCHSIZE = 1
a0d0e21e 1686 CODE:
8e07c86e 1687 CurrentDB = db ;
b76802f5 1688 RETVAL = GetArrayLength(aTHX_ db) ;
a0d0e21e 1689 OUTPUT:
1690 RETVAL
1691
1692
1693#
1694# Now provide an interface to the rest of the DB functionality
1695#
1696
1697int
1698db_del(db, key, flags=0)
1699 DB_File db
1700 DBTKEY key
1701 u_int flags
df3728a2 1702 PREINIT:
1703 dMY_CXT;
1f70e1ea 1704 CODE:
8e07c86e 1705 CurrentDB = db ;
1f70e1ea 1706 RETVAL = db_del(db, key, flags) ;
1707#ifdef DB_VERSION_MAJOR
1708 if (RETVAL > 0)
1709 RETVAL = -1 ;
1710 else if (RETVAL == DB_NOTFOUND)
1711 RETVAL = 1 ;
1712#endif
1713 OUTPUT:
1714 RETVAL
a0d0e21e 1715
1716
1717int
1718db_get(db, key, value, flags=0)
1719 DB_File db
1720 DBTKEY key
a6ed719b 1721 DBT value = NO_INIT
a0d0e21e 1722 u_int flags
df3728a2 1723 PREINIT:
1724 dMY_CXT;
1f70e1ea 1725 CODE:
8e07c86e 1726 CurrentDB = db ;
ccb44e3b 1727 DBT_clear(value) ;
1f70e1ea 1728 RETVAL = db_get(db, key, value, flags) ;
1729#ifdef DB_VERSION_MAJOR
1730 if (RETVAL > 0)
1731 RETVAL = -1 ;
1732 else if (RETVAL == DB_NOTFOUND)
1733 RETVAL = 1 ;
1734#endif
a0d0e21e 1735 OUTPUT:
1f70e1ea 1736 RETVAL
a0d0e21e 1737 value
1738
1739int
1740db_put(db, key, value, flags=0)
1741 DB_File db
1742 DBTKEY key
1743 DBT value
1744 u_int flags
df3728a2 1745 PREINIT:
1746 dMY_CXT;
1f70e1ea 1747 CODE:
8e07c86e 1748 CurrentDB = db ;
1f70e1ea 1749 RETVAL = db_put(db, key, value, flags) ;
1750#ifdef DB_VERSION_MAJOR
1751 if (RETVAL > 0)
1752 RETVAL = -1 ;
1753 else if (RETVAL == DB_KEYEXIST)
1754 RETVAL = 1 ;
1755#endif
a0d0e21e 1756 OUTPUT:
1f70e1ea 1757 RETVAL
9d9477b1 1758 key if (flagSet(flags, R_IAFTER) || flagSet(flags, R_IBEFORE)) OutputKey(ST(1), key);
a0d0e21e 1759
1760int
1761db_fd(db)
1762 DB_File db
df3728a2 1763 PREINIT:
07200f1b 1764 dMY_CXT ;
1f70e1ea 1765 CODE:
8e07c86e 1766 CurrentDB = db ;
1f70e1ea 1767#ifdef DB_VERSION_MAJOR
1768 RETVAL = -1 ;
497b47a8 1769 {
1770 int status = 0 ;
1771 status = (db->in_memory
1772 ? -1
1773 : ((db->dbp)->fd)(db->dbp, &RETVAL) ) ;
1774 if (status != 0)
1775 RETVAL = -1 ;
1776 }
1f70e1ea 1777#else
1778 RETVAL = (db->in_memory
1779 ? -1
1780 : ((db->dbp)->fd)(db->dbp) ) ;
1781#endif
1782 OUTPUT:
1783 RETVAL
a0d0e21e 1784
1785int
1786db_sync(db, flags=0)
1787 DB_File db
1788 u_int flags
df3728a2 1789 PREINIT:
1790 dMY_CXT;
1f70e1ea 1791 CODE:
8e07c86e 1792 CurrentDB = db ;
1f70e1ea 1793 RETVAL = db_sync(db, flags) ;
1794#ifdef DB_VERSION_MAJOR
1795 if (RETVAL > 0)
1796 RETVAL = -1 ;
1797#endif
1798 OUTPUT:
1799 RETVAL
a0d0e21e 1800
1801
1802int
1803db_seq(db, key, value, flags)
1804 DB_File db
1805 DBTKEY key
a6ed719b 1806 DBT value = NO_INIT
a0d0e21e 1807 u_int flags
df3728a2 1808 PREINIT:
1809 dMY_CXT;
1f70e1ea 1810 CODE:
8e07c86e 1811 CurrentDB = db ;
ccb44e3b 1812 DBT_clear(value) ;
1f70e1ea 1813 RETVAL = db_seq(db, key, value, flags);
1814#ifdef DB_VERSION_MAJOR
1815 if (RETVAL > 0)
1816 RETVAL = -1 ;
1817 else if (RETVAL == DB_NOTFOUND)
1818 RETVAL = 1 ;
1819#endif
a0d0e21e 1820 OUTPUT:
1f70e1ea 1821 RETVAL
a0d0e21e 1822 key
1823 value
610ab055 1824
9fe6733a 1825SV *
1826filter_fetch_key(db, code)
1827 DB_File db
1828 SV * code
1829 SV * RETVAL = &PL_sv_undef ;
1830 CODE:
6a31061a 1831 DBM_setFilter(db->filter_fetch_key, code) ;
9fe6733a 1832
1833SV *
1834filter_store_key(db, code)
1835 DB_File db
1836 SV * code
1837 SV * RETVAL = &PL_sv_undef ;
1838 CODE:
6a31061a 1839 DBM_setFilter(db->filter_store_key, code) ;
9fe6733a 1840
1841SV *
1842filter_fetch_value(db, code)
1843 DB_File db
1844 SV * code
1845 SV * RETVAL = &PL_sv_undef ;
1846 CODE:
6a31061a 1847 DBM_setFilter(db->filter_fetch_value, code) ;
9fe6733a 1848
1849SV *
1850filter_store_value(db, code)
1851 DB_File db
1852 SV * code
1853 SV * RETVAL = &PL_sv_undef ;
1854 CODE:
6a31061a 1855 DBM_setFilter(db->filter_store_value, code) ;
9fe6733a 1856