5.004_5*: [PATCH] restore old behaviour of \1 in RE
[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
5 written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
1f70e1ea 6 last modified 20th Nov 1997
7 version 1.56
a0d0e21e 8
9 All comments/suggestions/problems are welcome
10
a0b8c8c1 11 Copyright (c) 1995, 1996, 1997 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
53
54
f6b705ef 55
a0d0e21e 56*/
57
58#include "EXTERN.h"
59#include "perl.h"
60#include "XSUB.h"
61
52e1cb5e 62/* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
63 * shortly #included by the <db.h>) __attribute__ to the possibly
64 * already defined __attribute__, for example by GNUC or by Perl. */
1f70e1ea 65
52e1cb5e 66#undef __attribute__
67
a0d0e21e 68#include <db.h>
69
70#include <fcntl.h>
71
1f70e1ea 72/* #define TRACE */
73
74
75
76#ifdef DB_VERSION_MAJOR
77
78/* map version 2 features & constants onto their version 1 equivalent */
79
80#ifdef DB_Prefix_t
81#undef DB_Prefix_t
82#endif
83#define DB_Prefix_t size_t
84
85#ifdef DB_Hash_t
86#undef DB_Hash_t
87#endif
88#define DB_Hash_t u_int32_t
89
90/* DBTYPE stays the same */
91/* HASHINFO, RECNOINFO and BTREEINFO map to DB_INFO */
92typedef DB_INFO INFO ;
93
94/* version 2 has db_recno_t in place of recno_t */
95typedef db_recno_t recno_t;
96
97
98#define R_CURSOR DB_SET_RANGE
99#define R_FIRST DB_FIRST
100#define R_IAFTER DB_AFTER
101#define R_IBEFORE DB_BEFORE
102#define R_LAST DB_LAST
103#define R_NEXT DB_NEXT
104#define R_NOOVERWRITE DB_NOOVERWRITE
105#define R_PREV DB_PREV
106#define R_SETCURSOR 0
107#define R_RECNOSYNC 0
108#define R_FIXEDLEN DB_FIXEDLEN
109#define R_DUP DB_DUP
110
111#define db_HA_hash h_hash
112#define db_HA_ffactor h_ffactor
113#define db_HA_nelem h_nelem
114#define db_HA_bsize db_pagesize
115#define db_HA_cachesize db_cachesize
116#define db_HA_lorder db_lorder
117
118#define db_BT_compare bt_compare
119#define db_BT_prefix bt_prefix
120#define db_BT_flags flags
121#define db_BT_psize db_pagesize
122#define db_BT_cachesize db_cachesize
123#define db_BT_lorder db_lorder
124#define db_BT_maxkeypage
125#define db_BT_minkeypage
126
127
128#define db_RE_reclen re_len
129#define db_RE_flags flags
130#define db_RE_bval re_pad
131#define db_RE_bfname re_source
132#define db_RE_psize db_pagesize
133#define db_RE_cachesize db_cachesize
134#define db_RE_lorder db_lorder
135
136#define TXN NULL,
137
138#define do_SEQ(db, key, value, flag) (db->cursor->c_get)(db->cursor, &key, &value, flag)
139
140
141#define DBT_flags(x) x.flags = 0
142#define DB_flags(x, v) x |= v
143
144#else /* db version 1.x */
145
146typedef union INFO {
147 HASHINFO hash ;
148 RECNOINFO recno ;
149 BTREEINFO btree ;
150 } INFO ;
151
152
610ab055 153#ifdef mDB_Prefix_t
154#ifdef DB_Prefix_t
155#undef DB_Prefix_t
156#endif
157#define DB_Prefix_t mDB_Prefix_t
158#endif
159
160#ifdef mDB_Hash_t
161#ifdef DB_Hash_t
162#undef DB_Hash_t
163#endif
164#define DB_Hash_t mDB_Hash_t
165#endif
166
1f70e1ea 167#define db_HA_hash hash.hash
168#define db_HA_ffactor hash.ffactor
169#define db_HA_nelem hash.nelem
170#define db_HA_bsize hash.bsize
171#define db_HA_cachesize hash.cachesize
172#define db_HA_lorder hash.lorder
173
174#define db_BT_compare btree.compare
175#define db_BT_prefix btree.prefix
176#define db_BT_flags btree.flags
177#define db_BT_psize btree.psize
178#define db_BT_cachesize btree.cachesize
179#define db_BT_lorder btree.lorder
180#define db_BT_maxkeypage btree.maxkeypage
181#define db_BT_minkeypage btree.minkeypage
182
183#define db_RE_reclen recno.reclen
184#define db_RE_flags recno.flags
185#define db_RE_bval recno.bval
186#define db_RE_bfname recno.bfname
187#define db_RE_psize recno.psize
188#define db_RE_cachesize recno.cachesize
189#define db_RE_lorder recno.lorder
190
191#define TXN
192
193#define do_SEQ(db, key, value, flag) (db->dbp->seq)(db->dbp, &key, &value, flag)
194#define DBT_flags(x)
195#define DB_flags(x, v)
196
197#endif /* db version 1 */
198
199
200
201#define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, TXN &key, flags)
202#define db_STORE(db, key, value, flags) ((db->dbp)->put)(db->dbp, TXN &key, &value, flags)
203#define db_FETCH(db, key, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
204
205#define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags)
206#define db_get(db, key, value, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
207#ifdef DB_VERSION_MAJOR
208#define db_DESTROY(db) ((db->dbp)->close)(db->dbp, 0)
209#define db_close(db) ((db->dbp)->close)(db->dbp, 0)
210#define db_del(db, key, flags) ((flags & R_CURSOR) \
211 ? ((db->cursor)->c_del)(db->cursor, 0) \
212 : ((db->dbp)->del)(db->dbp, NULL, &key, flags) )
213
214#else
215
216#define db_DESTROY(db) ((db->dbp)->close)(db->dbp)
217#define db_close(db) ((db->dbp)->close)(db->dbp)
218#define db_del(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags)
219#define db_put(db, key, value, flags) ((db->dbp)->put)(db->dbp, &key, &value, flags)
220
221#endif
222
223#define db_seq(db, key, value, flags) do_SEQ(db, key, value, flags)
610ab055 224
8e07c86e 225typedef struct {
226 DBTYPE type ;
227 DB * dbp ;
228 SV * compare ;
229 SV * prefix ;
230 SV * hash ;
a0b8c8c1 231 int in_memory ;
1f70e1ea 232 INFO info ;
233#ifdef DB_VERSION_MAJOR
234 DBC * cursor ;
235#endif
8e07c86e 236 } DB_File_type;
237
238typedef DB_File_type * DB_File ;
a0d0e21e 239typedef DBT DBTKEY ;
240
a0d0e21e 241
88108326 242#define OutputValue(arg, name) \
243 { if (RETVAL == 0) { \
244 sv_setpvn(arg, name.data, name.size) ; \
245 } \
246 }
a0d0e21e 247
248#define OutputKey(arg, name) \
1f70e1ea 249 { if (RETVAL == 0) \
a0d0e21e 250 { \
88108326 251 if (db->type != DB_RECNO) { \
a0d0e21e 252 sv_setpvn(arg, name.data, name.size); \
88108326 253 } \
a0d0e21e 254 else \
255 sv_setiv(arg, (I32)*(I32*)name.data - 1); \
256 } \
257 }
258
259/* Internal Global Data */
8e07c86e 260static recno_t Value ;
8e07c86e 261static recno_t zero = 0 ;
1f70e1ea 262static DB_File CurrentDB ;
263static DBTKEY empty ;
264
265#ifdef DB_VERSION_MAJOR
266
267static int
268db_put(db, key, value, flags)
269DB_File db ;
270DBTKEY key ;
271DBT value ;
272u_int flags ;
273
274{
275 int status ;
276
277 if (flags & R_CURSOR) {
278 status = ((db->cursor)->c_del)(db->cursor, 0);
279 if (status != 0)
280 return status ;
281
282 flags &= ~R_CURSOR ;
283 }
284
285 return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;
286
287}
288
289#endif /* DB_VERSION_MAJOR */
290
291static void
292GetVersionInfo()
293{
294 SV * ver_sv = perl_get_sv("DB_File::db_version", TRUE) ;
295#ifdef DB_VERSION_MAJOR
296 int Major, Minor, Patch ;
297
298 (void)db_version(&Major, &Minor, &Patch) ;
299
300 /* check that libdb is recent enough */
301 if (Major == 2 && Minor == 0 && Patch < 5)
302 croak("DB_File needs Berkeley DB 2.0.5 or greater, you have %d.%d.%d\n",
303 Major, Minor, Patch) ;
304
305#if PATCHLEVEL > 3
306 sv_setpvf(ver_sv, "%d.%d", Major, Minor) ;
307#else
308 {
309 char buffer[40] ;
310 sprintf(buffer, "%d.%d", Major, Minor) ;
311 sv_setpv(ver_sv, buffer) ;
312 }
313#endif
314
315#else
316 sv_setiv(ver_sv, 1) ;
317#endif
318
319}
a0d0e21e 320
321
322static int
323btree_compare(key1, key2)
324const DBT * key1 ;
325const DBT * key2 ;
326{
327 dSP ;
328 void * data1, * data2 ;
329 int retval ;
330 int count ;
331
332 data1 = key1->data ;
333 data2 = key2->data ;
334
335 /* As newSVpv will assume that the data pointer is a null terminated C
336 string if the size parameter is 0, make sure that data points to an
337 empty string if the length is 0
338 */
339 if (key1->size == 0)
340 data1 = "" ;
341 if (key2->size == 0)
342 data2 = "" ;
343
344 ENTER ;
345 SAVETMPS;
346
347 PUSHMARK(sp) ;
348 EXTEND(sp,2) ;
349 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
350 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
351 PUTBACK ;
352
8e07c86e 353 count = perl_call_sv(CurrentDB->compare, G_SCALAR);
a0d0e21e 354
355 SPAGAIN ;
356
357 if (count != 1)
ff0cee69 358 croak ("DB_File btree_compare: expected 1 return value from compare sub, got %d\n", count) ;
a0d0e21e 359
360 retval = POPi ;
361
362 PUTBACK ;
363 FREETMPS ;
364 LEAVE ;
365 return (retval) ;
366
367}
368
ecfc5424 369static DB_Prefix_t
a0d0e21e 370btree_prefix(key1, key2)
371const DBT * key1 ;
372const DBT * key2 ;
373{
374 dSP ;
375 void * data1, * data2 ;
376 int retval ;
377 int count ;
378
379 data1 = key1->data ;
380 data2 = key2->data ;
381
382 /* As newSVpv will assume that the data pointer is a null terminated C
383 string if the size parameter is 0, make sure that data points to an
384 empty string if the length is 0
385 */
386 if (key1->size == 0)
387 data1 = "" ;
388 if (key2->size == 0)
389 data2 = "" ;
390
391 ENTER ;
392 SAVETMPS;
393
394 PUSHMARK(sp) ;
395 EXTEND(sp,2) ;
396 PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
397 PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
398 PUTBACK ;
399
8e07c86e 400 count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
a0d0e21e 401
402 SPAGAIN ;
403
404 if (count != 1)
ff0cee69 405 croak ("DB_File btree_prefix: expected 1 return value from prefix sub, got %d\n", count) ;
a0d0e21e 406
407 retval = POPi ;
408
409 PUTBACK ;
410 FREETMPS ;
411 LEAVE ;
412
413 return (retval) ;
414}
415
ecfc5424 416static DB_Hash_t
a0d0e21e 417hash_cb(data, size)
418const void * data ;
419size_t size ;
420{
421 dSP ;
422 int retval ;
423 int count ;
424
425 if (size == 0)
426 data = "" ;
427
610ab055 428 /* DGH - Next two lines added to fix corrupted stack problem */
429 ENTER ;
430 SAVETMPS;
431
a0d0e21e 432 PUSHMARK(sp) ;
610ab055 433
a0d0e21e 434 XPUSHs(sv_2mortal(newSVpv((char*)data,size)));
435 PUTBACK ;
436
8e07c86e 437 count = perl_call_sv(CurrentDB->hash, G_SCALAR);
a0d0e21e 438
439 SPAGAIN ;
440
441 if (count != 1)
ff0cee69 442 croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ;
a0d0e21e 443
444 retval = POPi ;
445
446 PUTBACK ;
447 FREETMPS ;
448 LEAVE ;
449
450 return (retval) ;
451}
452
453
454#ifdef TRACE
455
456static void
457PrintHash(hash)
1f70e1ea 458INFO * hash ;
a0d0e21e 459{
460 printf ("HASH Info\n") ;
1f70e1ea 461 printf (" hash = %s\n",
462 (hash->db_HA_hash != NULL ? "redefined" : "default")) ;
463 printf (" bsize = %d\n", hash->db_HA_bsize) ;
464 printf (" ffactor = %d\n", hash->db_HA_ffactor) ;
465 printf (" nelem = %d\n", hash->db_HA_nelem) ;
466 printf (" cachesize = %d\n", hash->db_HA_cachesize) ;
467 printf (" lorder = %d\n", hash->db_HA_lorder) ;
a0d0e21e 468
469}
470
471static void
472PrintRecno(recno)
1f70e1ea 473INFO * recno ;
a0d0e21e 474{
475 printf ("RECNO Info\n") ;
1f70e1ea 476 printf (" flags = %d\n", recno->db_RE_flags) ;
477 printf (" cachesize = %d\n", recno->db_RE_cachesize) ;
478 printf (" psize = %d\n", recno->db_RE_psize) ;
479 printf (" lorder = %d\n", recno->db_RE_lorder) ;
480 printf (" reclen = %ul\n", (unsigned long)recno->db_RE_reclen) ;
481 printf (" bval = %d 0x%x\n", recno->db_RE_bval, recno->db_RE_bval) ;
482 printf (" bfname = %d [%s]\n", recno->db_RE_bfname, recno->db_RE_bfname) ;
a0d0e21e 483}
484
ff68c719 485static void
a0d0e21e 486PrintBtree(btree)
1f70e1ea 487INFO * btree ;
a0d0e21e 488{
489 printf ("BTREE Info\n") ;
1f70e1ea 490 printf (" compare = %s\n",
491 (btree->db_BT_compare ? "redefined" : "default")) ;
492 printf (" prefix = %s\n",
493 (btree->db_BT_prefix ? "redefined" : "default")) ;
494 printf (" flags = %d\n", btree->db_BT_flags) ;
495 printf (" cachesize = %d\n", btree->db_BT_cachesize) ;
496 printf (" psize = %d\n", btree->db_BT_psize) ;
497#ifndef DB_VERSION_MAJOR
498 printf (" maxkeypage = %d\n", btree->db_BT_maxkeypage) ;
499 printf (" minkeypage = %d\n", btree->db_BT_minkeypage) ;
500#endif
501 printf (" lorder = %d\n", btree->db_BT_lorder) ;
a0d0e21e 502}
503
504#else
505
506#define PrintRecno(recno)
507#define PrintHash(hash)
508#define PrintBtree(btree)
509
510#endif /* TRACE */
511
512
513static I32
514GetArrayLength(db)
1f70e1ea 515DB_File db ;
a0d0e21e 516{
517 DBT key ;
518 DBT value ;
519 int RETVAL ;
520
1f70e1ea 521 DBT_flags(key) ;
522 DBT_flags(value) ;
523 RETVAL = do_SEQ(db, key, value, R_LAST) ;
a0d0e21e 524 if (RETVAL == 0)
525 RETVAL = *(I32 *)key.data ;
1f70e1ea 526 else /* No key means empty file */
a0d0e21e 527 RETVAL = 0 ;
528
a0b8c8c1 529 return ((I32)RETVAL) ;
a0d0e21e 530}
531
88108326 532static recno_t
533GetRecnoKey(db, value)
534DB_File db ;
535I32 value ;
536{
537 if (value < 0) {
538 /* Get the length of the array */
1f70e1ea 539 I32 length = GetArrayLength(db) ;
88108326 540
541 /* check for attempt to write before start of array */
542 if (length + value + 1 <= 0)
ff0cee69 543 croak("Modification of non-creatable array value attempted, subscript %ld", (long)value) ;
88108326 544
545 value = length + value + 1 ;
546 }
547 else
548 ++ value ;
549
550 return value ;
a0d0e21e 551}
552
553static DB_File
05475680 554ParseOpenInfo(isHASH, name, flags, mode, sv)
555int isHASH ;
a0d0e21e 556char * name ;
557int flags ;
558int mode ;
559SV * sv ;
a0d0e21e 560{
561 SV ** svp;
562 HV * action ;
8c52afec 563 DB_File RETVAL;
a0d0e21e 564 void * openinfo = NULL ;
8c52afec 565 INFO * info;
1f70e1ea 566
567/* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
8c52afec 568 Newz(777, RETVAL, 1, DB_File_type) ;
569 info = &RETVAL->info ;
a0d0e21e 570
88108326 571 /* Default to HASH */
8e07c86e 572 RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
573 RETVAL->type = DB_HASH ;
a0d0e21e 574
610ab055 575 /* DGH - Next line added to avoid SEGV on existing hash DB */
576 CurrentDB = RETVAL;
577
a0b8c8c1 578 /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */
579 RETVAL->in_memory = (name == NULL) ;
580
a0d0e21e 581 if (sv)
582 {
583 if (! SvROK(sv) )
584 croak ("type parameter is not a reference") ;
585
36477c24 586 svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ;
587 if (svp && SvOK(*svp))
588 action = (HV*) SvRV(*svp) ;
589 else
590 croak("internal error") ;
610ab055 591
a0d0e21e 592 if (sv_isa(sv, "DB_File::HASHINFO"))
593 {
05475680 594
595 if (!isHASH)
596 croak("DB_File can only tie an associative array to a DB_HASH database") ;
597
8e07c86e 598 RETVAL->type = DB_HASH ;
610ab055 599 openinfo = (void*)info ;
a0d0e21e 600
601 svp = hv_fetch(action, "hash", 4, FALSE);
602
603 if (svp && SvOK(*svp))
604 {
1f70e1ea 605 info->db_HA_hash = hash_cb ;
8e07c86e 606 RETVAL->hash = newSVsv(*svp) ;
a0d0e21e 607 }
608 else
1f70e1ea 609 info->db_HA_hash = NULL ;
a0d0e21e 610
a0d0e21e 611 svp = hv_fetch(action, "ffactor", 7, FALSE);
1f70e1ea 612 info->db_HA_ffactor = svp ? SvIV(*svp) : 0;
a0d0e21e 613
614 svp = hv_fetch(action, "nelem", 5, FALSE);
1f70e1ea 615 info->db_HA_nelem = svp ? SvIV(*svp) : 0;
a0d0e21e 616
1f70e1ea 617 svp = hv_fetch(action, "bsize", 5, FALSE);
618 info->db_HA_bsize = svp ? SvIV(*svp) : 0;
619
a0d0e21e 620 svp = hv_fetch(action, "cachesize", 9, FALSE);
1f70e1ea 621 info->db_HA_cachesize = svp ? SvIV(*svp) : 0;
a0d0e21e 622
623 svp = hv_fetch(action, "lorder", 6, FALSE);
1f70e1ea 624 info->db_HA_lorder = svp ? SvIV(*svp) : 0;
a0d0e21e 625
626 PrintHash(info) ;
627 }
628 else if (sv_isa(sv, "DB_File::BTREEINFO"))
629 {
05475680 630 if (!isHASH)
631 croak("DB_File can only tie an associative array to a DB_BTREE database");
632
8e07c86e 633 RETVAL->type = DB_BTREE ;
610ab055 634 openinfo = (void*)info ;
a0d0e21e 635
636 svp = hv_fetch(action, "compare", 7, FALSE);
637 if (svp && SvOK(*svp))
638 {
1f70e1ea 639 info->db_BT_compare = btree_compare ;
8e07c86e 640 RETVAL->compare = newSVsv(*svp) ;
a0d0e21e 641 }
642 else
1f70e1ea 643 info->db_BT_compare = NULL ;
a0d0e21e 644
645 svp = hv_fetch(action, "prefix", 6, FALSE);
646 if (svp && SvOK(*svp))
647 {
1f70e1ea 648 info->db_BT_prefix = btree_prefix ;
8e07c86e 649 RETVAL->prefix = newSVsv(*svp) ;
a0d0e21e 650 }
651 else
1f70e1ea 652 info->db_BT_prefix = NULL ;
a0d0e21e 653
654 svp = hv_fetch(action, "flags", 5, FALSE);
1f70e1ea 655 info->db_BT_flags = svp ? SvIV(*svp) : 0;
a0d0e21e 656
657 svp = hv_fetch(action, "cachesize", 9, FALSE);
1f70e1ea 658 info->db_BT_cachesize = svp ? SvIV(*svp) : 0;
a0d0e21e 659
1f70e1ea 660#ifndef DB_VERSION_MAJOR
a0d0e21e 661 svp = hv_fetch(action, "minkeypage", 10, FALSE);
610ab055 662 info->btree.minkeypage = svp ? SvIV(*svp) : 0;
a0d0e21e 663
664 svp = hv_fetch(action, "maxkeypage", 10, FALSE);
610ab055 665 info->btree.maxkeypage = svp ? SvIV(*svp) : 0;
1f70e1ea 666#endif
a0d0e21e 667
668 svp = hv_fetch(action, "psize", 5, FALSE);
1f70e1ea 669 info->db_BT_psize = svp ? SvIV(*svp) : 0;
a0d0e21e 670
671 svp = hv_fetch(action, "lorder", 6, FALSE);
1f70e1ea 672 info->db_BT_lorder = svp ? SvIV(*svp) : 0;
a0d0e21e 673
674 PrintBtree(info) ;
675
676 }
677 else if (sv_isa(sv, "DB_File::RECNOINFO"))
678 {
05475680 679 if (isHASH)
680 croak("DB_File can only tie an array to a DB_RECNO database");
681
8e07c86e 682 RETVAL->type = DB_RECNO ;
610ab055 683 openinfo = (void *)info ;
a0d0e21e 684
1f70e1ea 685 info->db_RE_flags = 0 ;
686
a0d0e21e 687 svp = hv_fetch(action, "flags", 5, FALSE);
1f70e1ea 688 info->db_RE_flags = (u_long) (svp ? SvIV(*svp) : 0);
689
690 svp = hv_fetch(action, "reclen", 6, FALSE);
691 info->db_RE_reclen = (size_t) (svp ? SvIV(*svp) : 0);
a0d0e21e 692
693 svp = hv_fetch(action, "cachesize", 9, FALSE);
1f70e1ea 694 info->db_RE_cachesize = (u_int) (svp ? SvIV(*svp) : 0);
a0d0e21e 695
696 svp = hv_fetch(action, "psize", 5, FALSE);
1f70e1ea 697 info->db_RE_psize = (u_int) (svp ? SvIV(*svp) : 0);
a0d0e21e 698
699 svp = hv_fetch(action, "lorder", 6, FALSE);
1f70e1ea 700 info->db_RE_lorder = (int) (svp ? SvIV(*svp) : 0);
701
702#ifdef DB_VERSION_MAJOR
703 info->re_source = name ;
704 name = NULL ;
705#endif
706 svp = hv_fetch(action, "bfname", 6, FALSE);
707 if (svp && SvOK(*svp)) {
708 char * ptr = SvPV(*svp,na) ;
709#ifdef DB_VERSION_MAJOR
710 name = (char*) na ? ptr : NULL ;
711#else
712 info->db_RE_bfname = (char*) (na ? ptr : NULL) ;
713#endif
714 }
715 else
716#ifdef DB_VERSION_MAJOR
717 name = NULL ;
718#else
719 info->db_RE_bfname = NULL ;
720#endif
a0d0e21e 721
722 svp = hv_fetch(action, "bval", 4, FALSE);
1f70e1ea 723#ifdef DB_VERSION_MAJOR
a0d0e21e 724 if (svp && SvOK(*svp))
725 {
1f70e1ea 726 int value ;
a0d0e21e 727 if (SvPOK(*svp))
1f70e1ea 728 value = (int)*SvPV(*svp, na) ;
a0d0e21e 729 else
1f70e1ea 730 value = SvIV(*svp) ;
731
732 if (info->flags & DB_FIXEDLEN) {
733 info->re_pad = value ;
734 info->flags |= DB_PAD ;
735 }
736 else {
737 info->re_delim = value ;
738 info->flags |= DB_DELIMITER ;
739 }
740
741 }
742#else
743 if (svp && SvOK(*svp))
744 {
745 if (SvPOK(*svp))
746 info->db_RE_bval = (u_char)*SvPV(*svp, na) ;
747 else
748 info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ;
749 DB_flags(info->flags, DB_DELIMITER) ;
750
a0d0e21e 751 }
752 else
753 {
1f70e1ea 754 if (info->db_RE_flags & R_FIXEDLEN)
755 info->db_RE_bval = (u_char) ' ' ;
a0d0e21e 756 else
1f70e1ea 757 info->db_RE_bval = (u_char) '\n' ;
758 DB_flags(info->flags, DB_DELIMITER) ;
a0d0e21e 759 }
1f70e1ea 760#endif
a0d0e21e 761
1f70e1ea 762#ifdef DB_RENUMBER
763 info->flags |= DB_RENUMBER ;
764#endif
765
a0d0e21e 766 PrintRecno(info) ;
767 }
768 else
769 croak("type is not of type DB_File::HASHINFO, DB_File::BTREEINFO or DB_File::RECNOINFO");
770 }
771
772
88108326 773 /* OS2 Specific Code */
774#ifdef OS2
775#ifdef __EMX__
776 flags |= O_BINARY;
777#endif /* __EMX__ */
778#endif /* OS2 */
a0d0e21e 779
1f70e1ea 780#ifdef DB_VERSION_MAJOR
781
782 {
783 int Flags = 0 ;
784 int status ;
785
786 /* Map 1.x flags to 2.x flags */
787 if ((flags & O_CREAT) == O_CREAT)
788 Flags |= DB_CREATE ;
789
790#ifdef O_NONBLOCK
791 if ((flags & O_NONBLOCK) == O_NONBLOCK)
792 Flags |= DB_EXCL ;
793#endif
794
795#if O_RDONLY == 0
796 if (flags == O_RDONLY)
797#else
798 if (flags & O_RDONLY) == O_RDONLY)
799#endif
800 Flags |= DB_RDONLY ;
801
802#ifdef O_NONBLOCK
803 if ((flags & O_TRUNC) == O_TRUNC)
804 Flags |= DB_TRUNCATE ;
805#endif
806
807 status = db_open(name, RETVAL->type, Flags, mode, NULL, openinfo, &RETVAL->dbp) ;
808 if (status == 0)
809 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor) ;
810
811 if (status)
812 RETVAL->dbp = NULL ;
813
814 }
815#else
88108326 816 RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ;
1f70e1ea 817#endif
a0d0e21e 818
819 return (RETVAL) ;
820}
821
822
823static int
824not_here(s)
825char *s;
826{
827 croak("DB_File::%s not implemented on this architecture", s);
828 return -1;
829}
830
831static double
832constant(name, arg)
833char *name;
834int arg;
835{
836 errno = 0;
837 switch (*name) {
838 case 'A':
839 break;
840 case 'B':
841 if (strEQ(name, "BTREEMAGIC"))
842#ifdef BTREEMAGIC
843 return BTREEMAGIC;
844#else
845 goto not_there;
846#endif
847 if (strEQ(name, "BTREEVERSION"))
848#ifdef BTREEVERSION
849 return BTREEVERSION;
850#else
851 goto not_there;
852#endif
853 break;
854 case 'C':
855 break;
856 case 'D':
857 if (strEQ(name, "DB_LOCK"))
858#ifdef DB_LOCK
859 return DB_LOCK;
860#else
861 goto not_there;
862#endif
863 if (strEQ(name, "DB_SHMEM"))
864#ifdef DB_SHMEM
865 return DB_SHMEM;
866#else
867 goto not_there;
868#endif
869 if (strEQ(name, "DB_TXN"))
870#ifdef DB_TXN
871 return (U32)DB_TXN;
872#else
873 goto not_there;
874#endif
875 break;
876 case 'E':
877 break;
878 case 'F':
879 break;
880 case 'G':
881 break;
882 case 'H':
883 if (strEQ(name, "HASHMAGIC"))
884#ifdef HASHMAGIC
885 return HASHMAGIC;
886#else
887 goto not_there;
888#endif
889 if (strEQ(name, "HASHVERSION"))
890#ifdef HASHVERSION
891 return HASHVERSION;
892#else
893 goto not_there;
894#endif
895 break;
896 case 'I':
897 break;
898 case 'J':
899 break;
900 case 'K':
901 break;
902 case 'L':
903 break;
904 case 'M':
905 if (strEQ(name, "MAX_PAGE_NUMBER"))
906#ifdef MAX_PAGE_NUMBER
907 return (U32)MAX_PAGE_NUMBER;
908#else
909 goto not_there;
910#endif
911 if (strEQ(name, "MAX_PAGE_OFFSET"))
912#ifdef MAX_PAGE_OFFSET
913 return MAX_PAGE_OFFSET;
914#else
915 goto not_there;
916#endif
917 if (strEQ(name, "MAX_REC_NUMBER"))
918#ifdef MAX_REC_NUMBER
919 return (U32)MAX_REC_NUMBER;
920#else
921 goto not_there;
922#endif
923 break;
924 case 'N':
925 break;
926 case 'O':
927 break;
928 case 'P':
929 break;
930 case 'Q':
931 break;
932 case 'R':
933 if (strEQ(name, "RET_ERROR"))
934#ifdef RET_ERROR
935 return RET_ERROR;
936#else
937 goto not_there;
938#endif
939 if (strEQ(name, "RET_SPECIAL"))
940#ifdef RET_SPECIAL
941 return RET_SPECIAL;
942#else
943 goto not_there;
944#endif
945 if (strEQ(name, "RET_SUCCESS"))
946#ifdef RET_SUCCESS
947 return RET_SUCCESS;
948#else
949 goto not_there;
950#endif
951 if (strEQ(name, "R_CURSOR"))
952#ifdef R_CURSOR
953 return R_CURSOR;
954#else
955 goto not_there;
956#endif
957 if (strEQ(name, "R_DUP"))
958#ifdef R_DUP
959 return R_DUP;
960#else
961 goto not_there;
962#endif
963 if (strEQ(name, "R_FIRST"))
964#ifdef R_FIRST
965 return R_FIRST;
966#else
967 goto not_there;
968#endif
969 if (strEQ(name, "R_FIXEDLEN"))
970#ifdef R_FIXEDLEN
971 return R_FIXEDLEN;
972#else
973 goto not_there;
974#endif
975 if (strEQ(name, "R_IAFTER"))
976#ifdef R_IAFTER
977 return R_IAFTER;
978#else
979 goto not_there;
980#endif
981 if (strEQ(name, "R_IBEFORE"))
982#ifdef R_IBEFORE
983 return R_IBEFORE;
984#else
985 goto not_there;
986#endif
987 if (strEQ(name, "R_LAST"))
988#ifdef R_LAST
989 return R_LAST;
990#else
991 goto not_there;
992#endif
993 if (strEQ(name, "R_NEXT"))
994#ifdef R_NEXT
995 return R_NEXT;
996#else
997 goto not_there;
998#endif
999 if (strEQ(name, "R_NOKEY"))
1000#ifdef R_NOKEY
1001 return R_NOKEY;
1002#else
1003 goto not_there;
1004#endif
1005 if (strEQ(name, "R_NOOVERWRITE"))
1006#ifdef R_NOOVERWRITE
1007 return R_NOOVERWRITE;
1008#else
1009 goto not_there;
1010#endif
1011 if (strEQ(name, "R_PREV"))
1012#ifdef R_PREV
1013 return R_PREV;
1014#else
1015 goto not_there;
1016#endif
1017 if (strEQ(name, "R_RECNOSYNC"))
1018#ifdef R_RECNOSYNC
1019 return R_RECNOSYNC;
1020#else
1021 goto not_there;
1022#endif
1023 if (strEQ(name, "R_SETCURSOR"))
1024#ifdef R_SETCURSOR
1025 return R_SETCURSOR;
1026#else
1027 goto not_there;
1028#endif
1029 if (strEQ(name, "R_SNAPSHOT"))
1030#ifdef R_SNAPSHOT
1031 return R_SNAPSHOT;
1032#else
1033 goto not_there;
1034#endif
1035 break;
1036 case 'S':
1037 break;
1038 case 'T':
1039 break;
1040 case 'U':
1041 break;
1042 case 'V':
1043 break;
1044 case 'W':
1045 break;
1046 case 'X':
1047 break;
1048 case 'Y':
1049 break;
1050 case 'Z':
1051 break;
1052 case '_':
a0d0e21e 1053 break;
1054 }
1055 errno = EINVAL;
1056 return 0;
1057
1058not_there:
1059 errno = ENOENT;
1060 return 0;
1061}
1062
1063MODULE = DB_File PACKAGE = DB_File PREFIX = db_
1064
1f70e1ea 1065BOOT:
1066 {
1067 GetVersionInfo() ;
1068
1069 empty.data = &zero ;
1070 empty.size = sizeof(recno_t) ;
1071 DBT_flags(empty) ;
1072 }
1073
a0d0e21e 1074double
1075constant(name,arg)
1076 char * name
1077 int arg
1078
1079
1080DB_File
05475680 1081db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_HASH)
1082 int isHASH
a0d0e21e 1083 char * dbtype
1084 int flags
1085 int mode
1086 CODE:
1087 {
1088 char * name = (char *) NULL ;
1089 SV * sv = (SV *) NULL ;
1090
05475680 1091 if (items >= 3 && SvOK(ST(2)))
1092 name = (char*) SvPV(ST(2), na) ;
a0d0e21e 1093
05475680 1094 if (items == 6)
1095 sv = ST(5) ;
a0d0e21e 1096
05475680 1097 RETVAL = ParseOpenInfo(isHASH, name, flags, mode, sv) ;
4633a7c4 1098 if (RETVAL->dbp == NULL)
1099 RETVAL = NULL ;
a0d0e21e 1100 }
1101 OUTPUT:
1102 RETVAL
1103
a0d0e21e 1104int
1105db_DESTROY(db)
1106 DB_File db
8e07c86e 1107 INIT:
1108 CurrentDB = db ;
1109 CLEANUP:
1110 if (db->hash)
1111 SvREFCNT_dec(db->hash) ;
1112 if (db->compare)
1113 SvREFCNT_dec(db->compare) ;
1114 if (db->prefix)
1115 SvREFCNT_dec(db->prefix) ;
1116 Safefree(db) ;
1f70e1ea 1117#ifdef DB_VERSION_MAJOR
1118 if (RETVAL > 0)
1119 RETVAL = -1 ;
1120#endif
a0d0e21e 1121
1122
1123int
1124db_DELETE(db, key, flags=0)
1125 DB_File db
1126 DBTKEY key
1127 u_int flags
8e07c86e 1128 INIT:
1129 CurrentDB = db ;
a0d0e21e 1130
f6b705ef 1131
1132int
1133db_EXISTS(db, key)
1134 DB_File db
1135 DBTKEY key
1136 CODE:
1137 {
1138 DBT value ;
1139
1f70e1ea 1140 DBT_flags(value) ;
f6b705ef 1141 CurrentDB = db ;
1f70e1ea 1142 RETVAL = (((db->dbp)->get)(db->dbp, TXN &key, &value, 0) == 0) ;
f6b705ef 1143 }
1144 OUTPUT:
1145 RETVAL
1146
a0d0e21e 1147int
1148db_FETCH(db, key, flags=0)
1149 DB_File db
1150 DBTKEY key
1151 u_int flags
1152 CODE:
1153 {
1f70e1ea 1154 DBT value ;
a0d0e21e 1155
1f70e1ea 1156 DBT_flags(value) ;
8e07c86e 1157 CurrentDB = db ;
1f70e1ea 1158 /* RETVAL = ((db->dbp)->get)(db->dbp, TXN &key, &value, flags) ; */
1159 RETVAL = db_get(db, key, value, flags) ;
a0d0e21e 1160 ST(0) = sv_newmortal();
1f70e1ea 1161 if (RETVAL == 0)
a0d0e21e 1162 sv_setpvn(ST(0), value.data, value.size);
1163 }
1164
1165int
1166db_STORE(db, key, value, flags=0)
1167 DB_File db
1168 DBTKEY key
1169 DBT value
1170 u_int flags
8e07c86e 1171 INIT:
1172 CurrentDB = db ;
a0d0e21e 1173
1174
1175int
1176db_FIRSTKEY(db)
1177 DB_File db
1178 CODE:
1179 {
1f70e1ea 1180 DBTKEY key ;
a0d0e21e 1181 DBT value ;
4633a7c4 1182 DB * Db = db->dbp ;
a0d0e21e 1183
1f70e1ea 1184 DBT_flags(key) ;
1185 DBT_flags(value) ;
8e07c86e 1186 CurrentDB = db ;
1f70e1ea 1187 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
a0d0e21e 1188 ST(0) = sv_newmortal();
1189 if (RETVAL == 0)
1190 {
05475680 1191 if (db->type != DB_RECNO)
a0d0e21e 1192 sv_setpvn(ST(0), key.data, key.size);
1193 else
1194 sv_setiv(ST(0), (I32)*(I32*)key.data - 1);
1195 }
1196 }
1197
1198int
1199db_NEXTKEY(db, key)
1200 DB_File db
1201 DBTKEY key
1202 CODE:
1203 {
1204 DBT value ;
4633a7c4 1205 DB * Db = db->dbp ;
a0d0e21e 1206
1f70e1ea 1207 DBT_flags(value) ;
8e07c86e 1208 CurrentDB = db ;
1f70e1ea 1209 RETVAL = do_SEQ(db, key, value, R_NEXT) ;
a0d0e21e 1210 ST(0) = sv_newmortal();
1211 if (RETVAL == 0)
1212 {
05475680 1213 if (db->type != DB_RECNO)
a0d0e21e 1214 sv_setpvn(ST(0), key.data, key.size);
1215 else
1216 sv_setiv(ST(0), (I32)*(I32*)key.data - 1);
1217 }
1218 }
1219
1220#
1221# These would be nice for RECNO
1222#
1223
1224int
1225unshift(db, ...)
1226 DB_File db
1227 CODE:
1228 {
1229 DBTKEY key ;
1230 DBT value ;
1231 int i ;
1232 int One ;
4633a7c4 1233 DB * Db = db->dbp ;
a0d0e21e 1234
1f70e1ea 1235 DBT_flags(key) ;
1236 DBT_flags(value) ;
8e07c86e 1237 CurrentDB = db ;
1f70e1ea 1238#ifdef DB_VERSION_MAJOR
1239 /* get the first value */
1240 RETVAL = do_SEQ(db, key, value, DB_FIRST) ;
1241 RETVAL = 0 ;
1242#else
a0d0e21e 1243 RETVAL = -1 ;
1f70e1ea 1244#endif
a0d0e21e 1245 for (i = items-1 ; i > 0 ; --i)
1246 {
1247 value.data = SvPV(ST(i), na) ;
1248 value.size = na ;
1249 One = 1 ;
1250 key.data = &One ;
1251 key.size = sizeof(int) ;
1f70e1ea 1252#ifdef DB_VERSION_MAJOR
1253 RETVAL = (db->cursor->c_put)(db->cursor, &key, &value, DB_BEFORE) ;
1254#else
4633a7c4 1255 RETVAL = (Db->put)(Db, &key, &value, R_IBEFORE) ;
1f70e1ea 1256#endif
a0d0e21e 1257 if (RETVAL != 0)
1258 break;
1259 }
1260 }
1261 OUTPUT:
1262 RETVAL
1263
1264I32
1265pop(db)
1266 DB_File db
1267 CODE:
1268 {
1269 DBTKEY key ;
1270 DBT value ;
4633a7c4 1271 DB * Db = db->dbp ;
a0d0e21e 1272
1f70e1ea 1273 DBT_flags(key) ;
1274 DBT_flags(value) ;
8e07c86e 1275 CurrentDB = db ;
1f70e1ea 1276
a0d0e21e 1277 /* First get the final value */
1f70e1ea 1278 RETVAL = do_SEQ(db, key, value, R_LAST) ;
a0d0e21e 1279 ST(0) = sv_newmortal();
1280 /* Now delete it */
1281 if (RETVAL == 0)
1282 {
f6b705ef 1283 /* the call to del will trash value, so take a copy now */
1284 sv_setpvn(ST(0), value.data, value.size);
1f70e1ea 1285 RETVAL = db_del(db, key, R_CURSOR) ;
f6b705ef 1286 if (RETVAL != 0)
1287 sv_setsv(ST(0), &sv_undef);
a0d0e21e 1288 }
1289 }
1290
1291I32
1292shift(db)
1293 DB_File db
1294 CODE:
1295 {
a0d0e21e 1296 DBT value ;
f6b705ef 1297 DBTKEY key ;
4633a7c4 1298 DB * Db = db->dbp ;
a0d0e21e 1299
1f70e1ea 1300 DBT_flags(key) ;
1301 DBT_flags(value) ;
8e07c86e 1302 CurrentDB = db ;
a0d0e21e 1303 /* get the first value */
1f70e1ea 1304 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
a0d0e21e 1305 ST(0) = sv_newmortal();
1306 /* Now delete it */
1307 if (RETVAL == 0)
1308 {
f6b705ef 1309 /* the call to del will trash value, so take a copy now */
1310 sv_setpvn(ST(0), value.data, value.size);
1f70e1ea 1311 RETVAL = db_del(db, key, R_CURSOR) ;
f6b705ef 1312 if (RETVAL != 0)
1313 sv_setsv (ST(0), &sv_undef) ;
a0d0e21e 1314 }
1315 }
1316
1317
1318I32
1319push(db, ...)
1320 DB_File db
1321 CODE:
1322 {
1323 DBTKEY key ;
8e07c86e 1324 DBTKEY * keyptr = &key ;
a0d0e21e 1325 DBT value ;
4633a7c4 1326 DB * Db = db->dbp ;
a0d0e21e 1327 int i ;
1328
1f70e1ea 1329 DBT_flags(key) ;
1330 DBT_flags(value) ;
8e07c86e 1331 CurrentDB = db ;
a0d0e21e 1332 /* Set the Cursor to the Last element */
1f70e1ea 1333 RETVAL = do_SEQ(db, key, value, R_LAST) ;
8e07c86e 1334 if (RETVAL >= 0)
a0d0e21e 1335 {
8e07c86e 1336 if (RETVAL == 1)
1337 keyptr = &empty ;
1f70e1ea 1338#ifdef DB_VERSION_MAJOR
1339 for (i = 1 ; i < items ; ++i)
1340 {
1341
1342 ++ (* (int*)key.data) ;
1343 value.data = SvPV(ST(i), na) ;
1344 value.size = na ;
1345 RETVAL = (Db->put)(Db, NULL, &key, &value, 0) ;
1346 if (RETVAL != 0)
1347 break;
1348 }
1349#else
8e07c86e 1350 for (i = items - 1 ; i > 0 ; --i)
1351 {
1352 value.data = SvPV(ST(i), na) ;
1353 value.size = na ;
4633a7c4 1354 RETVAL = (Db->put)(Db, keyptr, &value, R_IAFTER) ;
8e07c86e 1355 if (RETVAL != 0)
1356 break;
1357 }
1f70e1ea 1358#endif
a0d0e21e 1359 }
1360 }
1361 OUTPUT:
1362 RETVAL
1363
1364
1365I32
1366length(db)
1367 DB_File db
1368 CODE:
8e07c86e 1369 CurrentDB = db ;
1f70e1ea 1370 RETVAL = GetArrayLength(db) ;
a0d0e21e 1371 OUTPUT:
1372 RETVAL
1373
1374
1375#
1376# Now provide an interface to the rest of the DB functionality
1377#
1378
1379int
1380db_del(db, key, flags=0)
1381 DB_File db
1382 DBTKEY key
1383 u_int flags
1f70e1ea 1384 CODE:
8e07c86e 1385 CurrentDB = db ;
1f70e1ea 1386 RETVAL = db_del(db, key, flags) ;
1387#ifdef DB_VERSION_MAJOR
1388 if (RETVAL > 0)
1389 RETVAL = -1 ;
1390 else if (RETVAL == DB_NOTFOUND)
1391 RETVAL = 1 ;
1392#endif
1393 OUTPUT:
1394 RETVAL
a0d0e21e 1395
1396
1397int
1398db_get(db, key, value, flags=0)
1399 DB_File db
1400 DBTKEY key
a6ed719b 1401 DBT value = NO_INIT
a0d0e21e 1402 u_int flags
1f70e1ea 1403 CODE:
8e07c86e 1404 CurrentDB = db ;
1f70e1ea 1405 DBT_flags(value) ;
1406 RETVAL = db_get(db, key, value, flags) ;
1407#ifdef DB_VERSION_MAJOR
1408 if (RETVAL > 0)
1409 RETVAL = -1 ;
1410 else if (RETVAL == DB_NOTFOUND)
1411 RETVAL = 1 ;
1412#endif
a0d0e21e 1413 OUTPUT:
1f70e1ea 1414 RETVAL
a0d0e21e 1415 value
1416
1417int
1418db_put(db, key, value, flags=0)
1419 DB_File db
1420 DBTKEY key
1421 DBT value
1422 u_int flags
1f70e1ea 1423 CODE:
8e07c86e 1424 CurrentDB = db ;
1f70e1ea 1425 RETVAL = db_put(db, key, value, flags) ;
1426#ifdef DB_VERSION_MAJOR
1427 if (RETVAL > 0)
1428 RETVAL = -1 ;
1429 else if (RETVAL == DB_KEYEXIST)
1430 RETVAL = 1 ;
1431#endif
a0d0e21e 1432 OUTPUT:
1f70e1ea 1433 RETVAL
a0d0e21e 1434 key if (flags & (R_IAFTER|R_IBEFORE)) OutputKey(ST(1), key);
1435
1436int
1437db_fd(db)
1438 DB_File db
1f70e1ea 1439 int status = 0 ;
1440 CODE:
8e07c86e 1441 CurrentDB = db ;
1f70e1ea 1442#ifdef DB_VERSION_MAJOR
1443 RETVAL = -1 ;
1444 status = (db->in_memory
1445 ? -1
1446 : ((db->dbp)->fd)(db->dbp, &RETVAL) ) ;
1447 if (status != 0)
1448 RETVAL = -1 ;
1449#else
1450 RETVAL = (db->in_memory
1451 ? -1
1452 : ((db->dbp)->fd)(db->dbp) ) ;
1453#endif
1454 OUTPUT:
1455 RETVAL
a0d0e21e 1456
1457int
1458db_sync(db, flags=0)
1459 DB_File db
1460 u_int flags
1f70e1ea 1461 CODE:
8e07c86e 1462 CurrentDB = db ;
1f70e1ea 1463 RETVAL = db_sync(db, flags) ;
1464#ifdef DB_VERSION_MAJOR
1465 if (RETVAL > 0)
1466 RETVAL = -1 ;
1467#endif
1468 OUTPUT:
1469 RETVAL
a0d0e21e 1470
1471
1472int
1473db_seq(db, key, value, flags)
1474 DB_File db
1475 DBTKEY key
a6ed719b 1476 DBT value = NO_INIT
a0d0e21e 1477 u_int flags
1f70e1ea 1478 CODE:
8e07c86e 1479 CurrentDB = db ;
1f70e1ea 1480 DBT_flags(value) ;
1481 RETVAL = db_seq(db, key, value, flags);
1482#ifdef DB_VERSION_MAJOR
1483 if (RETVAL > 0)
1484 RETVAL = -1 ;
1485 else if (RETVAL == DB_NOTFOUND)
1486 RETVAL = 1 ;
1487#endif
a0d0e21e 1488 OUTPUT:
1f70e1ea 1489 RETVAL
a0d0e21e 1490 key
1491 value
610ab055 1492