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