#17842 was only half the story
[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>
efc79c7d 6 last modified 1st September 2002
7 version 1.805
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 $_
f6b705ef 108
a0d0e21e 109*/
110
c6c619a9 111#define PERL_NO_GET_CONTEXT
a0d0e21e 112#include "EXTERN.h"
113#include "perl.h"
114#include "XSUB.h"
115
07200f1b 116#ifdef _NOT_CORE
117# include "ppport.h"
cad2e5aa 118#endif
119
640374d0 120/* Mention DB_VERSION_MAJOR_CFG, DB_VERSION_MINOR_CFG, and
121 DB_VERSION_PATCH_CFG here so that Configure pulls them all in. */
122
52e1cb5e 123/* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
124 * shortly #included by the <db.h>) __attribute__ to the possibly
125 * already defined __attribute__, for example by GNUC or by Perl. */
1f70e1ea 126
39793c41 127/* #if DB_VERSION_MAJOR_CFG < 2 */
128#ifndef DB_VERSION_MAJOR
129# undef __attribute__
640374d0 130#endif
131
ccb44e3b 132#ifdef COMPAT185
133# include <db_185.h>
134#else
135# include <db.h>
136#endif
a0d0e21e 137
39793c41 138/* Wall starts with 5.7.x */
139
140#if PERL_REVISION > 5 || (PERL_REVISION == 5 && PERL_VERSION >= 7)
141
142/* Since we dropped the gccish definition of __attribute__ we will want
143 * to redefine dNOOP, however (so that dTHX continues to work). Yes,
144 * all this means that we can't do attribute checking on the DB_File,
145 * boo, hiss. */
146# ifndef DB_VERSION_MAJOR
147
148# undef dNOOP
149# define dNOOP extern int Perl___notused
150
151 /* Ditto for dXSARGS. */
152# undef dXSARGS
153# define dXSARGS \
154 dSP; dMARK; \
155 I32 ax = mark - PL_stack_base + 1; \
156 I32 items = sp - mark
157
158# endif
159
160/* avoid -Wall; DB_File xsubs never make use of `ix' setup for ALIASes */
161# undef dXSI32
162# define dXSI32 dNOOP
163
164#endif /* Perl >= 5.7 */
b92372bc 165
a0d0e21e 166#include <fcntl.h>
167
1f70e1ea 168/* #define TRACE */
169
ccb44e3b 170#ifdef TRACE
171# define Trace(x) printf x
172#else
173# define Trace(x)
174#endif
175
1f70e1ea 176
ccb44e3b 177#define DBT_clear(x) Zero(&x, 1, DBT) ;
1f70e1ea 178
179#ifdef DB_VERSION_MAJOR
180
ccb44e3b 181#if DB_VERSION_MAJOR == 2
182# define BERKELEY_DB_1_OR_2
183#endif
184
73969f8f 185#if DB_VERSION_MAJOR > 3 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 2)
186# define AT_LEAST_DB_3_2
187#endif
188
efc79c7d 189#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
190# define AT_LEAST_DB_4_1
191#endif
192
1f70e1ea 193/* map version 2 features & constants onto their version 1 equivalent */
194
195#ifdef DB_Prefix_t
2c2d71f5 196# undef DB_Prefix_t
1f70e1ea 197#endif
198#define DB_Prefix_t size_t
199
200#ifdef DB_Hash_t
2c2d71f5 201# undef DB_Hash_t
1f70e1ea 202#endif
203#define DB_Hash_t u_int32_t
204
205/* DBTYPE stays the same */
206/* HASHINFO, RECNOINFO and BTREEINFO map to DB_INFO */
ccb44e3b 207#if DB_VERSION_MAJOR == 2
208 typedef DB_INFO INFO ;
209#else /* DB_VERSION_MAJOR > 2 */
210# define DB_FIXEDLEN (0x8000)
211#endif /* DB_VERSION_MAJOR == 2 */
1f70e1ea 212
213/* version 2 has db_recno_t in place of recno_t */
214typedef db_recno_t recno_t;
215
216
217#define R_CURSOR DB_SET_RANGE
218#define R_FIRST DB_FIRST
219#define R_IAFTER DB_AFTER
220#define R_IBEFORE DB_BEFORE
221#define R_LAST DB_LAST
222#define R_NEXT DB_NEXT
223#define R_NOOVERWRITE DB_NOOVERWRITE
224#define R_PREV DB_PREV
ccb44e3b 225
a62982a8 226#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
ccb44e3b 227# define R_SETCURSOR 0x800000
a62982a8 228#else
ccb44e3b 229# define R_SETCURSOR (-100)
a62982a8 230#endif
ccb44e3b 231
1f70e1ea 232#define R_RECNOSYNC 0
233#define R_FIXEDLEN DB_FIXEDLEN
234#define R_DUP DB_DUP
235
ccb44e3b 236
1f70e1ea 237#define db_HA_hash h_hash
238#define db_HA_ffactor h_ffactor
239#define db_HA_nelem h_nelem
240#define db_HA_bsize db_pagesize
241#define db_HA_cachesize db_cachesize
242#define db_HA_lorder db_lorder
243
244#define db_BT_compare bt_compare
245#define db_BT_prefix bt_prefix
246#define db_BT_flags flags
247#define db_BT_psize db_pagesize
248#define db_BT_cachesize db_cachesize
249#define db_BT_lorder db_lorder
250#define db_BT_maxkeypage
251#define db_BT_minkeypage
252
253
254#define db_RE_reclen re_len
255#define db_RE_flags flags
256#define db_RE_bval re_pad
257#define db_RE_bfname re_source
258#define db_RE_psize db_pagesize
259#define db_RE_cachesize db_cachesize
260#define db_RE_lorder db_lorder
261
262#define TXN NULL,
263
264#define do_SEQ(db, key, value, flag) (db->cursor->c_get)(db->cursor, &key, &value, flag)
265
266
267#define DBT_flags(x) x.flags = 0
268#define DB_flags(x, v) x |= v
269
9d9477b1 270#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
ccb44e3b 271# define flagSet(flags, bitmask) ((flags) & (bitmask))
9d9477b1 272#else
ccb44e3b 273# define flagSet(flags, bitmask) (((flags) & DB_OPFLAGS_MASK) == (bitmask))
9d9477b1 274#endif
275
1f70e1ea 276#else /* db version 1.x */
277
73969f8f 278#define BERKELEY_DB_1
ccb44e3b 279#define BERKELEY_DB_1_OR_2
280
1f70e1ea 281typedef union INFO {
282 HASHINFO hash ;
283 RECNOINFO recno ;
284 BTREEINFO btree ;
285 } INFO ;
286
287
610ab055 288#ifdef mDB_Prefix_t
ccb44e3b 289# ifdef DB_Prefix_t
290# undef DB_Prefix_t
291# endif
292# define DB_Prefix_t mDB_Prefix_t
610ab055 293#endif
294
295#ifdef mDB_Hash_t
ccb44e3b 296# ifdef DB_Hash_t
297# undef DB_Hash_t
298# endif
299# define DB_Hash_t mDB_Hash_t
610ab055 300#endif
301
1f70e1ea 302#define db_HA_hash hash.hash
303#define db_HA_ffactor hash.ffactor
304#define db_HA_nelem hash.nelem
305#define db_HA_bsize hash.bsize
306#define db_HA_cachesize hash.cachesize
307#define db_HA_lorder hash.lorder
308
309#define db_BT_compare btree.compare
310#define db_BT_prefix btree.prefix
311#define db_BT_flags btree.flags
312#define db_BT_psize btree.psize
313#define db_BT_cachesize btree.cachesize
314#define db_BT_lorder btree.lorder
315#define db_BT_maxkeypage btree.maxkeypage
316#define db_BT_minkeypage btree.minkeypage
317
318#define db_RE_reclen recno.reclen
319#define db_RE_flags recno.flags
320#define db_RE_bval recno.bval
321#define db_RE_bfname recno.bfname
322#define db_RE_psize recno.psize
323#define db_RE_cachesize recno.cachesize
324#define db_RE_lorder recno.lorder
325
326#define TXN
327
328#define do_SEQ(db, key, value, flag) (db->dbp->seq)(db->dbp, &key, &value, flag)
329#define DBT_flags(x)
330#define DB_flags(x, v)
9d9477b1 331#define flagSet(flags, bitmask) ((flags) & (bitmask))
1f70e1ea 332
333#endif /* db version 1 */
334
335
336
962cee9f 337#define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, TXN &key, 0)
338#define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, 0)
339#define db_FETCH(db, key, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, 0)
1f70e1ea 340
341#define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags)
342#define db_get(db, key, value, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
9d9477b1 343
1f70e1ea 344#ifdef DB_VERSION_MAJOR
efc79c7d 345#define db_DESTROY(db) (!db->aborted && ( db->cursor->c_close(db->cursor),\
346 (db->dbp->close)(db->dbp, 0) ))
1f70e1ea 347#define db_close(db) ((db->dbp)->close)(db->dbp, 0)
9d9477b1 348#define db_del(db, key, flags) (flagSet(flags, R_CURSOR) \
1f70e1ea 349 ? ((db->cursor)->c_del)(db->cursor, 0) \
350 : ((db->dbp)->del)(db->dbp, NULL, &key, flags) )
351
ccb44e3b 352#else /* ! DB_VERSION_MAJOR */
1f70e1ea 353
efc79c7d 354#define db_DESTROY(db) (!db->aborted && ((db->dbp)->close)(db->dbp))
1f70e1ea 355#define db_close(db) ((db->dbp)->close)(db->dbp)
356#define db_del(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags)
357#define db_put(db, key, value, flags) ((db->dbp)->put)(db->dbp, &key, &value, flags)
358
ccb44e3b 359#endif /* ! DB_VERSION_MAJOR */
1f70e1ea 360
9d9477b1 361
1f70e1ea 362#define db_seq(db, key, value, flags) do_SEQ(db, key, value, flags)
610ab055 363
8e07c86e 364typedef struct {
365 DBTYPE type ;
366 DB * dbp ;
367 SV * compare ;
efc79c7d 368 bool in_compare ;
8e07c86e 369 SV * prefix ;
efc79c7d 370 bool in_prefix ;
8e07c86e 371 SV * hash ;
efc79c7d 372 bool in_hash ;
373 bool aborted ;
a0b8c8c1 374 int in_memory ;
ccb44e3b 375#ifdef BERKELEY_DB_1_OR_2
1f70e1ea 376 INFO info ;
ccb44e3b 377#endif
1f70e1ea 378#ifdef DB_VERSION_MAJOR
379 DBC * cursor ;
380#endif
9fe6733a 381 SV * filter_fetch_key ;
382 SV * filter_store_key ;
383 SV * filter_fetch_value ;
384 SV * filter_store_value ;
385 int filtering ;
9fe6733a 386
8e07c86e 387 } DB_File_type;
388
389typedef DB_File_type * DB_File ;
a0d0e21e 390typedef DBT DBTKEY ;
391
045291aa 392#define my_sv_setpvn(sv, d, s) sv_setpvn(sv, (s ? d : (void*)""), s)
a0d0e21e 393
9fe6733a 394#define OutputValue(arg, name) \
395 { if (RETVAL == 0) { \
396 my_sv_setpvn(arg, name.data, name.size) ; \
efc79c7d 397 TAINT; \
398 SvTAINTED_on(arg); \
6a31061a 399 DBM_ckFilter(arg, filter_fetch_value,"filter_fetch_value") ; \
9fe6733a 400 } \
88108326 401 }
a0d0e21e 402
9fe6733a 403#define OutputKey(arg, name) \
404 { if (RETVAL == 0) \
405 { \
406 if (db->type != DB_RECNO) { \
407 my_sv_setpvn(arg, name.data, name.size); \
408 } \
409 else \
410 sv_setiv(arg, (I32)*(I32*)name.data - 1); \
efc79c7d 411 TAINT; \
412 SvTAINTED_on(arg); \
6a31061a 413 DBM_ckFilter(arg, filter_fetch_key,"filter_fetch_key") ; \
9fe6733a 414 } \
a0d0e21e 415 }
416
c6c92ad9 417#define my_SvUV32(sv) ((u_int32_t)SvUV(sv))
045291aa 418
39793c41 419#ifdef CAN_PROTOTYPE
420extern void __getBerkeleyDBInfo(void);
421#endif
422
a0d0e21e 423/* Internal Global Data */
07200f1b 424
df3728a2 425#define MY_CXT_KEY "DB_File::_guts" XS_VERSION
426
427typedef struct {
428 recno_t x_Value;
429 recno_t x_zero;
430 DB_File x_CurrentDB;
431 DBTKEY x_empty;
432} my_cxt_t;
433
434START_MY_CXT
435
436#define Value (MY_CXT.x_Value)
437#define zero (MY_CXT.x_zero)
438#define CurrentDB (MY_CXT.x_CurrentDB)
439#define empty (MY_CXT.x_empty)
1f70e1ea 440
efc79c7d 441#define ERR_BUFF "DB_File::Error"
442
1f70e1ea 443#ifdef DB_VERSION_MAJOR
444
445static int
2c2d71f5 446#ifdef CAN_PROTOTYPE
b76802f5 447db_put(DB_File db, DBTKEY key, DBT value, u_int flags)
2c2d71f5 448#else
449db_put(db, key, value, flags)
450DB_File db ;
451DBTKEY key ;
452DBT value ;
453u_int flags ;
454#endif
1f70e1ea 455{
456 int status ;
457
2c2d71f5 458 if (flagSet(flags, R_IAFTER) || flagSet(flags, R_IBEFORE)) {
459 DBC * temp_cursor ;
460 DBT l_key, l_value;
461
462#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
463 if (((db->dbp)->cursor)(db->dbp, NULL, &temp_cursor) != 0)
9d9477b1 464#else
2c2d71f5 465 if (((db->dbp)->cursor)(db->dbp, NULL, &temp_cursor, 0) != 0)
9d9477b1 466#endif
2c2d71f5 467 return (-1) ;
468
469 memset(&l_key, 0, sizeof(l_key));
470 l_key.data = key.data;
471 l_key.size = key.size;
472 memset(&l_value, 0, sizeof(l_value));
473 l_value.data = value.data;
474 l_value.size = value.size;
475
476 if ( temp_cursor->c_get(temp_cursor, &l_key, &l_value, DB_SET) != 0) {
477 (void)temp_cursor->c_close(temp_cursor);
478 return (-1);
479 }
480
481 status = temp_cursor->c_put(temp_cursor, &key, &value, flags);
482 (void)temp_cursor->c_close(temp_cursor);
483
484 return (status) ;
485 }
486
487
488 if (flagSet(flags, R_CURSOR)) {
489 return ((db->cursor)->c_put)(db->cursor, &key, &value, DB_CURRENT);
490 }
9d9477b1 491
2c2d71f5 492 if (flagSet(flags, R_SETCURSOR)) {
493 if ((db->dbp)->put(db->dbp, NULL, &key, &value, 0) != 0)
494 return -1 ;
495 return ((db->cursor)->c_get)(db->cursor, &key, &value, DB_SET_RANGE);
496
1f70e1ea 497 }
498
499 return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;
500
501}
502
503#endif /* DB_VERSION_MAJOR */
504
efc79c7d 505static void
506tidyUp(DB_File db)
507{
508 /* db_DESTROY(db); */
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 ;
efc79c7d 546 DB_File keep_CurrentDB = CurrentDB;
a0d0e21e 547
efc79c7d 548
549 if (CurrentDB->in_compare) {
550 tidyUp(CurrentDB);
551 croak ("DB_File btree_compare: recursion detected\n") ;
552 }
553
c5da4faf 554 data1 = (char *) key1->data ;
555 data2 = (char *) key2->data ;
cad2e5aa 556
2c2d71f5 557#ifndef newSVpvn
a0d0e21e 558 /* As newSVpv will assume that the data pointer is a null terminated C
559 string if the size parameter is 0, make sure that data points to an
560 empty string if the length is 0
561 */
562 if (key1->size == 0)
563 data1 = "" ;
564 if (key2->size == 0)
565 data2 = "" ;
2c2d71f5 566#endif
cad2e5aa 567
a0d0e21e 568 ENTER ;
569 SAVETMPS;
570
924508f0 571 PUSHMARK(SP) ;
572 EXTEND(SP,2) ;
2c2d71f5 573 PUSHs(sv_2mortal(newSVpvn(data1,key1->size)));
574 PUSHs(sv_2mortal(newSVpvn(data2,key2->size)));
a0d0e21e 575 PUTBACK ;
576
efc79c7d 577 CurrentDB->in_compare = TRUE;
578
8e07c86e 579 count = perl_call_sv(CurrentDB->compare, G_SCALAR);
a0d0e21e 580
efc79c7d 581 CurrentDB = keep_CurrentDB;
582 CurrentDB->in_compare = FALSE;
583
a0d0e21e 584 SPAGAIN ;
585
efc79c7d 586 if (count != 1){
587 tidyUp(CurrentDB);
ff0cee69 588 croak ("DB_File btree_compare: expected 1 return value from compare sub, got %d\n", count) ;
efc79c7d 589 }
a0d0e21e 590
591 retval = POPi ;
592
593 PUTBACK ;
594 FREETMPS ;
595 LEAVE ;
efc79c7d 596
a0d0e21e 597 return (retval) ;
598
599}
600
ecfc5424 601static DB_Prefix_t
73969f8f 602#ifdef AT_LEAST_DB_3_2
603
604#ifdef CAN_PROTOTYPE
605btree_prefix(DB * db, const DBT *key1, const DBT *key2)
606#else
607btree_prefix(db, key1, key2)
608Db * db ;
609const DBT * key1 ;
610const DBT * key2 ;
611#endif
612
613#else /* Berkeley DB < 3.2 */
614
2c2d71f5 615#ifdef CAN_PROTOTYPE
b76802f5 616btree_prefix(const DBT *key1, const DBT *key2)
2c2d71f5 617#else
618btree_prefix(key1, key2)
619const DBT * key1 ;
620const DBT * key2 ;
621#endif
73969f8f 622
623#endif
a0d0e21e 624{
2c2d71f5 625#ifdef dTHX
b76802f5 626 dTHX;
2c2d71f5 627#endif
a0d0e21e 628 dSP ;
df3728a2 629 dMY_CXT ;
c5da4faf 630 char * data1, * data2 ;
a0d0e21e 631 int retval ;
632 int count ;
efc79c7d 633 DB_File keep_CurrentDB = CurrentDB;
a0d0e21e 634
efc79c7d 635 if (CurrentDB->in_prefix){
636 tidyUp(CurrentDB);
637 croak ("DB_File btree_prefix: recursion detected\n") ;
638 }
639
c5da4faf 640 data1 = (char *) key1->data ;
641 data2 = (char *) key2->data ;
cad2e5aa 642
2c2d71f5 643#ifndef newSVpvn
a0d0e21e 644 /* As newSVpv will assume that the data pointer is a null terminated C
645 string if the size parameter is 0, make sure that data points to an
646 empty string if the length is 0
647 */
648 if (key1->size == 0)
649 data1 = "" ;
650 if (key2->size == 0)
651 data2 = "" ;
2c2d71f5 652#endif
cad2e5aa 653
a0d0e21e 654 ENTER ;
655 SAVETMPS;
656
924508f0 657 PUSHMARK(SP) ;
658 EXTEND(SP,2) ;
2c2d71f5 659 PUSHs(sv_2mortal(newSVpvn(data1,key1->size)));
660 PUSHs(sv_2mortal(newSVpvn(data2,key2->size)));
a0d0e21e 661 PUTBACK ;
662
efc79c7d 663 CurrentDB->in_prefix = TRUE;
664
8e07c86e 665 count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
a0d0e21e 666
efc79c7d 667 CurrentDB = keep_CurrentDB;
668 CurrentDB->in_prefix = FALSE;
669
a0d0e21e 670 SPAGAIN ;
671
efc79c7d 672 if (count != 1){
673 tidyUp(CurrentDB);
ff0cee69 674 croak ("DB_File btree_prefix: expected 1 return value from prefix sub, got %d\n", count) ;
efc79c7d 675 }
a0d0e21e 676
677 retval = POPi ;
678
679 PUTBACK ;
680 FREETMPS ;
681 LEAVE ;
682
683 return (retval) ;
684}
685
3245f058 686
73969f8f 687#ifdef BERKELEY_DB_1
a56128cb 688# define HASH_CB_SIZE_TYPE size_t
689#else
690# define HASH_CB_SIZE_TYPE u_int32_t
691#endif
692
ecfc5424 693static DB_Hash_t
73969f8f 694#ifdef AT_LEAST_DB_3_2
695
696#ifdef CAN_PROTOTYPE
697hash_cb(DB * db, const void *data, u_int32_t size)
698#else
699hash_cb(db, data, size)
700DB * db ;
701const void * data ;
702HASH_CB_SIZE_TYPE size ;
703#endif
704
705#else /* Berkeley DB < 3.2 */
706
2c2d71f5 707#ifdef CAN_PROTOTYPE
a56128cb 708hash_cb(const void *data, HASH_CB_SIZE_TYPE size)
2c2d71f5 709#else
710hash_cb(data, size)
711const void * data ;
a56128cb 712HASH_CB_SIZE_TYPE size ;
2c2d71f5 713#endif
73969f8f 714
715#endif
a0d0e21e 716{
2c2d71f5 717#ifdef dTHX
b76802f5 718 dTHX;
2c2d71f5 719#endif
a0d0e21e 720 dSP ;
df3728a2 721 dMY_CXT;
a0d0e21e 722 int retval ;
723 int count ;
efc79c7d 724 DB_File keep_CurrentDB = CurrentDB;
725
726 if (CurrentDB->in_hash){
727 tidyUp(CurrentDB);
728 croak ("DB_File hash callback: recursion detected\n") ;
729 }
cad2e5aa 730
2c2d71f5 731#ifndef newSVpvn
a0d0e21e 732 if (size == 0)
733 data = "" ;
2c2d71f5 734#endif
cad2e5aa 735
610ab055 736 /* DGH - Next two lines added to fix corrupted stack problem */
737 ENTER ;
738 SAVETMPS;
739
924508f0 740 PUSHMARK(SP) ;
610ab055 741
2c2d71f5 742 XPUSHs(sv_2mortal(newSVpvn((char*)data,size)));
a0d0e21e 743 PUTBACK ;
744
efc79c7d 745 keep_CurrentDB->in_hash = TRUE;
746
8e07c86e 747 count = perl_call_sv(CurrentDB->hash, G_SCALAR);
a0d0e21e 748
efc79c7d 749 CurrentDB = keep_CurrentDB;
750 CurrentDB->in_hash = FALSE;
751
a0d0e21e 752 SPAGAIN ;
753
efc79c7d 754 if (count != 1){
755 tidyUp(CurrentDB);
ff0cee69 756 croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ;
efc79c7d 757 }
a0d0e21e 758
759 retval = POPi ;
760
761 PUTBACK ;
762 FREETMPS ;
763 LEAVE ;
764
765 return (retval) ;
766}
767
efc79c7d 768static void
769#ifdef CAN_PROTOTYPE
770db_errcall_cb(const char * db_errpfx, char * buffer)
771#else
772db_errcall_cb(db_errpfx, buffer)
773const char * db_errpfx;
774char * buffer;
775#endif
776{
777 SV * sv = perl_get_sv(ERR_BUFF, FALSE) ;
778 if (sv) {
779 if (db_errpfx)
780 sv_setpvf(sv, "%s: %s", db_errpfx, buffer) ;
781 else
782 sv_setpv(sv, buffer) ;
783 }
784}
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) ;
820 printf (" reclen = %ul\n", (unsigned long)recno->db_RE_reclen) ;
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) {
1431 RETVAL->dbp->set_errcall(RETVAL->dbp, db_errcall_cb) ;
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 {
efc79c7d 1458 SV * sv_err = perl_get_sv(ERR_BUFF, GV_ADD|GV_ADDMULTI) ;
df3728a2 1459 MY_CXT_INIT;
ccb44e3b 1460 __getBerkeleyDBInfo() ;
1f70e1ea 1461
ccb44e3b 1462 DBT_clear(empty) ;
1f70e1ea 1463 empty.data = &zero ;
1464 empty.size = sizeof(recno_t) ;
1f70e1ea 1465 }
1466
a0d0e21e 1467
1468
1469DB_File
05475680 1470db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_HASH)
1471 int isHASH
a0d0e21e 1472 char * dbtype
1473 int flags
1474 int mode
1475 CODE:
1476 {
1477 char * name = (char *) NULL ;
1478 SV * sv = (SV *) NULL ;
2d8e6c8d 1479 STRLEN n_a;
a0d0e21e 1480
05475680 1481 if (items >= 3 && SvOK(ST(2)))
2d8e6c8d 1482 name = (char*) SvPV(ST(2), n_a) ;
a0d0e21e 1483
05475680 1484 if (items == 6)
1485 sv = ST(5) ;
a0d0e21e 1486
b76802f5 1487 RETVAL = ParseOpenInfo(aTHX_ isHASH, name, flags, mode, sv) ;
4633a7c4 1488 if (RETVAL->dbp == NULL)
1489 RETVAL = NULL ;
a0d0e21e 1490 }
1491 OUTPUT:
1492 RETVAL
1493
a0d0e21e 1494int
1495db_DESTROY(db)
1496 DB_File db
df3728a2 1497 PREINIT:
1498 dMY_CXT;
8e07c86e 1499 INIT:
1500 CurrentDB = db ;
efc79c7d 1501 Trace(("DESTROY %p\n", db));
8e07c86e 1502 CLEANUP:
efc79c7d 1503 Trace(("DESTROY %p done\n", db));
8e07c86e 1504 if (db->hash)
1505 SvREFCNT_dec(db->hash) ;
1506 if (db->compare)
1507 SvREFCNT_dec(db->compare) ;
1508 if (db->prefix)
1509 SvREFCNT_dec(db->prefix) ;
9fe6733a 1510 if (db->filter_fetch_key)
1511 SvREFCNT_dec(db->filter_fetch_key) ;
1512 if (db->filter_store_key)
1513 SvREFCNT_dec(db->filter_store_key) ;
1514 if (db->filter_fetch_value)
1515 SvREFCNT_dec(db->filter_fetch_value) ;
1516 if (db->filter_store_value)
1517 SvREFCNT_dec(db->filter_store_value) ;
eb99164f 1518 safefree(db) ;
1f70e1ea 1519#ifdef DB_VERSION_MAJOR
1520 if (RETVAL > 0)
1521 RETVAL = -1 ;
1522#endif
a0d0e21e 1523
1524
1525int
1526db_DELETE(db, key, flags=0)
1527 DB_File db
1528 DBTKEY key
1529 u_int flags
df3728a2 1530 PREINIT:
1531 dMY_CXT;
8e07c86e 1532 INIT:
1533 CurrentDB = db ;
a0d0e21e 1534
f6b705ef 1535
1536int
1537db_EXISTS(db, key)
1538 DB_File db
1539 DBTKEY key
df3728a2 1540 PREINIT:
1541 dMY_CXT;
f6b705ef 1542 CODE:
1543 {
1544 DBT value ;
1545
ccb44e3b 1546 DBT_clear(value) ;
f6b705ef 1547 CurrentDB = db ;
1f70e1ea 1548 RETVAL = (((db->dbp)->get)(db->dbp, TXN &key, &value, 0) == 0) ;
f6b705ef 1549 }
1550 OUTPUT:
1551 RETVAL
1552
c6c619a9 1553void
a0d0e21e 1554db_FETCH(db, key, flags=0)
1555 DB_File db
1556 DBTKEY key
1557 u_int flags
c6c619a9 1558 PREINIT:
07200f1b 1559 dMY_CXT ;
1560 int RETVAL ;
a0d0e21e 1561 CODE:
1562 {
1f70e1ea 1563 DBT value ;
a0d0e21e 1564
ccb44e3b 1565 DBT_clear(value) ;
8e07c86e 1566 CurrentDB = db ;
1f70e1ea 1567 RETVAL = db_get(db, key, value, flags) ;
a0d0e21e 1568 ST(0) = sv_newmortal();
a9fd575d 1569 OutputValue(ST(0), value)
a0d0e21e 1570 }
1571
1572int
1573db_STORE(db, key, value, flags=0)
1574 DB_File db
1575 DBTKEY key
1576 DBT value
1577 u_int flags
df3728a2 1578 PREINIT:
1579 dMY_CXT;
8e07c86e 1580 INIT:
1581 CurrentDB = db ;
a0d0e21e 1582
1583
c6c619a9 1584void
a0d0e21e 1585db_FIRSTKEY(db)
1586 DB_File db
c6c619a9 1587 PREINIT:
07200f1b 1588 dMY_CXT ;
1589 int RETVAL ;
a0d0e21e 1590 CODE:
1591 {
1f70e1ea 1592 DBTKEY key ;
a0d0e21e 1593 DBT value ;
1594
ccb44e3b 1595 DBT_clear(key) ;
1596 DBT_clear(value) ;
8e07c86e 1597 CurrentDB = db ;
1f70e1ea 1598 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
a0d0e21e 1599 ST(0) = sv_newmortal();
a9fd575d 1600 OutputKey(ST(0), key) ;
a0d0e21e 1601 }
1602
c6c619a9 1603void
a0d0e21e 1604db_NEXTKEY(db, key)
1605 DB_File db
0bf2e707 1606 DBTKEY key = NO_INIT
c6c619a9 1607 PREINIT:
07200f1b 1608 dMY_CXT ;
1609 int RETVAL ;
a0d0e21e 1610 CODE:
1611 {
1612 DBT value ;
1613
0bf2e707 1614 DBT_clear(key) ;
ccb44e3b 1615 DBT_clear(value) ;
8e07c86e 1616 CurrentDB = db ;
1f70e1ea 1617 RETVAL = do_SEQ(db, key, value, R_NEXT) ;
a0d0e21e 1618 ST(0) = sv_newmortal();
a9fd575d 1619 OutputKey(ST(0), key) ;
a0d0e21e 1620 }
1621
1622#
1623# These would be nice for RECNO
1624#
1625
1626int
1627unshift(db, ...)
1628 DB_File db
045291aa 1629 ALIAS: UNSHIFT = 1
df3728a2 1630 PREINIT:
1631 dMY_CXT;
a0d0e21e 1632 CODE:
1633 {
1634 DBTKEY key ;
1635 DBT value ;
1636 int i ;
1637 int One ;
2d8e6c8d 1638 STRLEN n_a;
a0d0e21e 1639
ccb44e3b 1640 DBT_clear(key) ;
1641 DBT_clear(value) ;
8e07c86e 1642 CurrentDB = db ;
1f70e1ea 1643#ifdef DB_VERSION_MAJOR
1644 /* get the first value */
1645 RETVAL = do_SEQ(db, key, value, DB_FIRST) ;
1646 RETVAL = 0 ;
1647#else
a0d0e21e 1648 RETVAL = -1 ;
1f70e1ea 1649#endif
a0d0e21e 1650 for (i = items-1 ; i > 0 ; --i)
1651 {
2d8e6c8d 1652 value.data = SvPV(ST(i), n_a) ;
1653 value.size = n_a ;
a0d0e21e 1654 One = 1 ;
1655 key.data = &One ;
1656 key.size = sizeof(int) ;
1f70e1ea 1657#ifdef DB_VERSION_MAJOR
1658 RETVAL = (db->cursor->c_put)(db->cursor, &key, &value, DB_BEFORE) ;
1659#else
b7953727 1660 RETVAL = (db->dbp->put)(db->dbp, &key, &value, R_IBEFORE) ;
1f70e1ea 1661#endif
a0d0e21e 1662 if (RETVAL != 0)
1663 break;
1664 }
1665 }
1666 OUTPUT:
1667 RETVAL
1668
c6c619a9 1669void
a0d0e21e 1670pop(db)
1671 DB_File db
df3728a2 1672 PREINIT:
1673 dMY_CXT;
045291aa 1674 ALIAS: POP = 1
c6c619a9 1675 PREINIT:
07200f1b 1676 I32 RETVAL;
a0d0e21e 1677 CODE:
1678 {
1679 DBTKEY key ;
1680 DBT value ;
1681
ccb44e3b 1682 DBT_clear(key) ;
1683 DBT_clear(value) ;
8e07c86e 1684 CurrentDB = db ;
1f70e1ea 1685
a0d0e21e 1686 /* First get the final value */
1f70e1ea 1687 RETVAL = do_SEQ(db, key, value, R_LAST) ;
a0d0e21e 1688 ST(0) = sv_newmortal();
1689 /* Now delete it */
1690 if (RETVAL == 0)
1691 {
f6b705ef 1692 /* the call to del will trash value, so take a copy now */
a9fd575d 1693 OutputValue(ST(0), value) ;
1f70e1ea 1694 RETVAL = db_del(db, key, R_CURSOR) ;
f6b705ef 1695 if (RETVAL != 0)
6b88bc9c 1696 sv_setsv(ST(0), &PL_sv_undef);
a0d0e21e 1697 }
1698 }
1699
c6c619a9 1700void
a0d0e21e 1701shift(db)
1702 DB_File db
df3728a2 1703 PREINIT:
1704 dMY_CXT;
045291aa 1705 ALIAS: SHIFT = 1
c6c619a9 1706 PREINIT:
07200f1b 1707 I32 RETVAL;
a0d0e21e 1708 CODE:
1709 {
a0d0e21e 1710 DBT value ;
f6b705ef 1711 DBTKEY key ;
a0d0e21e 1712
ccb44e3b 1713 DBT_clear(key) ;
1714 DBT_clear(value) ;
8e07c86e 1715 CurrentDB = db ;
a0d0e21e 1716 /* get the first value */
1f70e1ea 1717 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
a0d0e21e 1718 ST(0) = sv_newmortal();
1719 /* Now delete it */
1720 if (RETVAL == 0)
1721 {
f6b705ef 1722 /* the call to del will trash value, so take a copy now */
a9fd575d 1723 OutputValue(ST(0), value) ;
1f70e1ea 1724 RETVAL = db_del(db, key, R_CURSOR) ;
f6b705ef 1725 if (RETVAL != 0)
6b88bc9c 1726 sv_setsv (ST(0), &PL_sv_undef) ;
a0d0e21e 1727 }
1728 }
1729
1730
1731I32
1732push(db, ...)
1733 DB_File db
df3728a2 1734 PREINIT:
1735 dMY_CXT;
045291aa 1736 ALIAS: PUSH = 1
a0d0e21e 1737 CODE:
1738 {
1739 DBTKEY key ;
1740 DBT value ;
4633a7c4 1741 DB * Db = db->dbp ;
a0d0e21e 1742 int i ;
2d8e6c8d 1743 STRLEN n_a;
ccb44e3b 1744 int keyval ;
a0d0e21e 1745
1f70e1ea 1746 DBT_flags(key) ;
1747 DBT_flags(value) ;
8e07c86e 1748 CurrentDB = db ;
ca63f0d2 1749 /* Set the Cursor to the Last element */
1750 RETVAL = do_SEQ(db, key, value, R_LAST) ;
ccb44e3b 1751#ifndef DB_VERSION_MAJOR
ca63f0d2 1752 if (RETVAL >= 0)
ccb44e3b 1753#endif
ca63f0d2 1754 {
ccb44e3b 1755 if (RETVAL == 0)
1756 keyval = *(int*)key.data ;
1757 else
1758 keyval = 0 ;
1759 for (i = 1 ; i < items ; ++i)
8e07c86e 1760 {
2d8e6c8d 1761 value.data = SvPV(ST(i), n_a) ;
1762 value.size = n_a ;
ccb44e3b 1763 ++ keyval ;
1764 key.data = &keyval ;
1765 key.size = sizeof(int) ;
1766 RETVAL = (Db->put)(Db, TXN &key, &value, 0) ;
8e07c86e 1767 if (RETVAL != 0)
1768 break;
1769 }
a0d0e21e 1770 }
1771 }
1772 OUTPUT:
1773 RETVAL
1774
a0d0e21e 1775I32
1776length(db)
1777 DB_File db
df3728a2 1778 PREINIT:
1779 dMY_CXT;
045291aa 1780 ALIAS: FETCHSIZE = 1
a0d0e21e 1781 CODE:
8e07c86e 1782 CurrentDB = db ;
b76802f5 1783 RETVAL = GetArrayLength(aTHX_ db) ;
a0d0e21e 1784 OUTPUT:
1785 RETVAL
1786
1787
1788#
1789# Now provide an interface to the rest of the DB functionality
1790#
1791
1792int
1793db_del(db, key, flags=0)
1794 DB_File db
1795 DBTKEY key
1796 u_int flags
df3728a2 1797 PREINIT:
1798 dMY_CXT;
1f70e1ea 1799 CODE:
8e07c86e 1800 CurrentDB = db ;
1f70e1ea 1801 RETVAL = db_del(db, key, flags) ;
1802#ifdef DB_VERSION_MAJOR
1803 if (RETVAL > 0)
1804 RETVAL = -1 ;
1805 else if (RETVAL == DB_NOTFOUND)
1806 RETVAL = 1 ;
1807#endif
1808 OUTPUT:
1809 RETVAL
a0d0e21e 1810
1811
1812int
1813db_get(db, key, value, flags=0)
1814 DB_File db
1815 DBTKEY key
a6ed719b 1816 DBT value = NO_INIT
a0d0e21e 1817 u_int flags
df3728a2 1818 PREINIT:
1819 dMY_CXT;
1f70e1ea 1820 CODE:
8e07c86e 1821 CurrentDB = db ;
ccb44e3b 1822 DBT_clear(value) ;
1f70e1ea 1823 RETVAL = db_get(db, key, value, flags) ;
1824#ifdef DB_VERSION_MAJOR
1825 if (RETVAL > 0)
1826 RETVAL = -1 ;
1827 else if (RETVAL == DB_NOTFOUND)
1828 RETVAL = 1 ;
1829#endif
a0d0e21e 1830 OUTPUT:
1f70e1ea 1831 RETVAL
a0d0e21e 1832 value
1833
1834int
1835db_put(db, key, value, flags=0)
1836 DB_File db
1837 DBTKEY key
1838 DBT value
1839 u_int flags
df3728a2 1840 PREINIT:
1841 dMY_CXT;
1f70e1ea 1842 CODE:
8e07c86e 1843 CurrentDB = db ;
1f70e1ea 1844 RETVAL = db_put(db, key, value, flags) ;
1845#ifdef DB_VERSION_MAJOR
1846 if (RETVAL > 0)
1847 RETVAL = -1 ;
1848 else if (RETVAL == DB_KEYEXIST)
1849 RETVAL = 1 ;
1850#endif
a0d0e21e 1851 OUTPUT:
1f70e1ea 1852 RETVAL
9d9477b1 1853 key if (flagSet(flags, R_IAFTER) || flagSet(flags, R_IBEFORE)) OutputKey(ST(1), key);
a0d0e21e 1854
1855int
1856db_fd(db)
1857 DB_File db
df3728a2 1858 PREINIT:
07200f1b 1859 dMY_CXT ;
1f70e1ea 1860 CODE:
8e07c86e 1861 CurrentDB = db ;
1f70e1ea 1862#ifdef DB_VERSION_MAJOR
1863 RETVAL = -1 ;
497b47a8 1864 {
1865 int status = 0 ;
1866 status = (db->in_memory
1867 ? -1
1868 : ((db->dbp)->fd)(db->dbp, &RETVAL) ) ;
1869 if (status != 0)
1870 RETVAL = -1 ;
1871 }
1f70e1ea 1872#else
1873 RETVAL = (db->in_memory
1874 ? -1
1875 : ((db->dbp)->fd)(db->dbp) ) ;
1876#endif
1877 OUTPUT:
1878 RETVAL
a0d0e21e 1879
1880int
1881db_sync(db, flags=0)
1882 DB_File db
1883 u_int flags
df3728a2 1884 PREINIT:
1885 dMY_CXT;
1f70e1ea 1886 CODE:
8e07c86e 1887 CurrentDB = db ;
1f70e1ea 1888 RETVAL = db_sync(db, flags) ;
1889#ifdef DB_VERSION_MAJOR
1890 if (RETVAL > 0)
1891 RETVAL = -1 ;
1892#endif
1893 OUTPUT:
1894 RETVAL
a0d0e21e 1895
1896
1897int
1898db_seq(db, key, value, flags)
1899 DB_File db
1900 DBTKEY key
a6ed719b 1901 DBT value = NO_INIT
a0d0e21e 1902 u_int flags
df3728a2 1903 PREINIT:
1904 dMY_CXT;
1f70e1ea 1905 CODE:
8e07c86e 1906 CurrentDB = db ;
ccb44e3b 1907 DBT_clear(value) ;
1f70e1ea 1908 RETVAL = db_seq(db, key, value, flags);
1909#ifdef DB_VERSION_MAJOR
1910 if (RETVAL > 0)
1911 RETVAL = -1 ;
1912 else if (RETVAL == DB_NOTFOUND)
1913 RETVAL = 1 ;
1914#endif
a0d0e21e 1915 OUTPUT:
1f70e1ea 1916 RETVAL
a0d0e21e 1917 key
1918 value
610ab055 1919
9fe6733a 1920SV *
1921filter_fetch_key(db, code)
1922 DB_File db
1923 SV * code
1924 SV * RETVAL = &PL_sv_undef ;
1925 CODE:
6a31061a 1926 DBM_setFilter(db->filter_fetch_key, code) ;
9fe6733a 1927
1928SV *
1929filter_store_key(db, code)
1930 DB_File db
1931 SV * code
1932 SV * RETVAL = &PL_sv_undef ;
1933 CODE:
6a31061a 1934 DBM_setFilter(db->filter_store_key, code) ;
9fe6733a 1935
1936SV *
1937filter_fetch_value(db, code)
1938 DB_File db
1939 SV * code
1940 SV * RETVAL = &PL_sv_undef ;
1941 CODE:
6a31061a 1942 DBM_setFilter(db->filter_fetch_value, code) ;
9fe6733a 1943
1944SV *
1945filter_store_value(db, code)
1946 DB_File db
1947 SV * code
1948 SV * RETVAL = &PL_sv_undef ;
1949 CODE:
6a31061a 1950 DBM_setFilter(db->filter_store_value, code) ;
9fe6733a 1951