Integrate win32 into ansiperl
[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 ;
8e07c86e 563 DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ;
a0d0e21e 564 void * openinfo = NULL ;
1f70e1ea 565 INFO * info = &RETVAL->info ;
566
567/* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
568 Zero(RETVAL, 1, DB_File_type) ;
a0d0e21e 569
88108326 570 /* Default to HASH */
8e07c86e 571 RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ;
572 RETVAL->type = DB_HASH ;
a0d0e21e 573
610ab055 574 /* DGH - Next line added to avoid SEGV on existing hash DB */
575 CurrentDB = RETVAL;
576
a0b8c8c1 577 /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */
578 RETVAL->in_memory = (name == NULL) ;
579
a0d0e21e 580 if (sv)
581 {
582 if (! SvROK(sv) )
583 croak ("type parameter is not a reference") ;
584
36477c24 585 svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ;
586 if (svp && SvOK(*svp))
587 action = (HV*) SvRV(*svp) ;
588 else
589 croak("internal error") ;
610ab055 590
a0d0e21e 591 if (sv_isa(sv, "DB_File::HASHINFO"))
592 {
05475680 593
594 if (!isHASH)
595 croak("DB_File can only tie an associative array to a DB_HASH database") ;
596
8e07c86e 597 RETVAL->type = DB_HASH ;
610ab055 598 openinfo = (void*)info ;
a0d0e21e 599
600 svp = hv_fetch(action, "hash", 4, FALSE);
601
602 if (svp && SvOK(*svp))
603 {
1f70e1ea 604 info->db_HA_hash = hash_cb ;
8e07c86e 605 RETVAL->hash = newSVsv(*svp) ;
a0d0e21e 606 }
607 else
1f70e1ea 608 info->db_HA_hash = NULL ;
a0d0e21e 609
a0d0e21e 610 svp = hv_fetch(action, "ffactor", 7, FALSE);
1f70e1ea 611 info->db_HA_ffactor = svp ? SvIV(*svp) : 0;
a0d0e21e 612
613 svp = hv_fetch(action, "nelem", 5, FALSE);
1f70e1ea 614 info->db_HA_nelem = svp ? SvIV(*svp) : 0;
a0d0e21e 615
1f70e1ea 616 svp = hv_fetch(action, "bsize", 5, FALSE);
617 info->db_HA_bsize = svp ? SvIV(*svp) : 0;
618
a0d0e21e 619 svp = hv_fetch(action, "cachesize", 9, FALSE);
1f70e1ea 620 info->db_HA_cachesize = svp ? SvIV(*svp) : 0;
a0d0e21e 621
622 svp = hv_fetch(action, "lorder", 6, FALSE);
1f70e1ea 623 info->db_HA_lorder = svp ? SvIV(*svp) : 0;
a0d0e21e 624
625 PrintHash(info) ;
626 }
627 else if (sv_isa(sv, "DB_File::BTREEINFO"))
628 {
05475680 629 if (!isHASH)
630 croak("DB_File can only tie an associative array to a DB_BTREE database");
631
8e07c86e 632 RETVAL->type = DB_BTREE ;
610ab055 633 openinfo = (void*)info ;
a0d0e21e 634
635 svp = hv_fetch(action, "compare", 7, FALSE);
636 if (svp && SvOK(*svp))
637 {
1f70e1ea 638 info->db_BT_compare = btree_compare ;
8e07c86e 639 RETVAL->compare = newSVsv(*svp) ;
a0d0e21e 640 }
641 else
1f70e1ea 642 info->db_BT_compare = NULL ;
a0d0e21e 643
644 svp = hv_fetch(action, "prefix", 6, FALSE);
645 if (svp && SvOK(*svp))
646 {
1f70e1ea 647 info->db_BT_prefix = btree_prefix ;
8e07c86e 648 RETVAL->prefix = newSVsv(*svp) ;
a0d0e21e 649 }
650 else
1f70e1ea 651 info->db_BT_prefix = NULL ;
a0d0e21e 652
653 svp = hv_fetch(action, "flags", 5, FALSE);
1f70e1ea 654 info->db_BT_flags = svp ? SvIV(*svp) : 0;
a0d0e21e 655
656 svp = hv_fetch(action, "cachesize", 9, FALSE);
1f70e1ea 657 info->db_BT_cachesize = svp ? SvIV(*svp) : 0;
a0d0e21e 658
1f70e1ea 659#ifndef DB_VERSION_MAJOR
a0d0e21e 660 svp = hv_fetch(action, "minkeypage", 10, FALSE);
610ab055 661 info->btree.minkeypage = svp ? SvIV(*svp) : 0;
a0d0e21e 662
663 svp = hv_fetch(action, "maxkeypage", 10, FALSE);
610ab055 664 info->btree.maxkeypage = svp ? SvIV(*svp) : 0;
1f70e1ea 665#endif
a0d0e21e 666
667 svp = hv_fetch(action, "psize", 5, FALSE);
1f70e1ea 668 info->db_BT_psize = svp ? SvIV(*svp) : 0;
a0d0e21e 669
670 svp = hv_fetch(action, "lorder", 6, FALSE);
1f70e1ea 671 info->db_BT_lorder = svp ? SvIV(*svp) : 0;
a0d0e21e 672
673 PrintBtree(info) ;
674
675 }
676 else if (sv_isa(sv, "DB_File::RECNOINFO"))
677 {
05475680 678 if (isHASH)
679 croak("DB_File can only tie an array to a DB_RECNO database");
680
8e07c86e 681 RETVAL->type = DB_RECNO ;
610ab055 682 openinfo = (void *)info ;
a0d0e21e 683
1f70e1ea 684 info->db_RE_flags = 0 ;
685
a0d0e21e 686 svp = hv_fetch(action, "flags", 5, FALSE);
1f70e1ea 687 info->db_RE_flags = (u_long) (svp ? SvIV(*svp) : 0);
688
689 svp = hv_fetch(action, "reclen", 6, FALSE);
690 info->db_RE_reclen = (size_t) (svp ? SvIV(*svp) : 0);
a0d0e21e 691
692 svp = hv_fetch(action, "cachesize", 9, FALSE);
1f70e1ea 693 info->db_RE_cachesize = (u_int) (svp ? SvIV(*svp) : 0);
a0d0e21e 694
695 svp = hv_fetch(action, "psize", 5, FALSE);
1f70e1ea 696 info->db_RE_psize = (u_int) (svp ? SvIV(*svp) : 0);
a0d0e21e 697
698 svp = hv_fetch(action, "lorder", 6, FALSE);
1f70e1ea 699 info->db_RE_lorder = (int) (svp ? SvIV(*svp) : 0);
700
701#ifdef DB_VERSION_MAJOR
702 info->re_source = name ;
703 name = NULL ;
704#endif
705 svp = hv_fetch(action, "bfname", 6, FALSE);
706 if (svp && SvOK(*svp)) {
707 char * ptr = SvPV(*svp,na) ;
708#ifdef DB_VERSION_MAJOR
709 name = (char*) na ? ptr : NULL ;
710#else
711 info->db_RE_bfname = (char*) (na ? ptr : NULL) ;
712#endif
713 }
714 else
715#ifdef DB_VERSION_MAJOR
716 name = NULL ;
717#else
718 info->db_RE_bfname = NULL ;
719#endif
a0d0e21e 720
721 svp = hv_fetch(action, "bval", 4, FALSE);
1f70e1ea 722#ifdef DB_VERSION_MAJOR
a0d0e21e 723 if (svp && SvOK(*svp))
724 {
1f70e1ea 725 int value ;
a0d0e21e 726 if (SvPOK(*svp))
1f70e1ea 727 value = (int)*SvPV(*svp, na) ;
a0d0e21e 728 else
1f70e1ea 729 value = SvIV(*svp) ;
730
731 if (info->flags & DB_FIXEDLEN) {
732 info->re_pad = value ;
733 info->flags |= DB_PAD ;
734 }
735 else {
736 info->re_delim = value ;
737 info->flags |= DB_DELIMITER ;
738 }
739
740 }
741#else
742 if (svp && SvOK(*svp))
743 {
744 if (SvPOK(*svp))
745 info->db_RE_bval = (u_char)*SvPV(*svp, na) ;
746 else
747 info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ;
748 DB_flags(info->flags, DB_DELIMITER) ;
749
a0d0e21e 750 }
751 else
752 {
1f70e1ea 753 if (info->db_RE_flags & R_FIXEDLEN)
754 info->db_RE_bval = (u_char) ' ' ;
a0d0e21e 755 else
1f70e1ea 756 info->db_RE_bval = (u_char) '\n' ;
757 DB_flags(info->flags, DB_DELIMITER) ;
a0d0e21e 758 }
1f70e1ea 759#endif
a0d0e21e 760
1f70e1ea 761#ifdef DB_RENUMBER
762 info->flags |= DB_RENUMBER ;
763#endif
764
a0d0e21e 765 PrintRecno(info) ;
766 }
767 else
768 croak("type is not of type DB_File::HASHINFO, DB_File::BTREEINFO or DB_File::RECNOINFO");
769 }
770
771
88108326 772 /* OS2 Specific Code */
773#ifdef OS2
774#ifdef __EMX__
775 flags |= O_BINARY;
776#endif /* __EMX__ */
777#endif /* OS2 */
a0d0e21e 778
1f70e1ea 779#ifdef DB_VERSION_MAJOR
780
781 {
782 int Flags = 0 ;
783 int status ;
784
785 /* Map 1.x flags to 2.x flags */
786 if ((flags & O_CREAT) == O_CREAT)
787 Flags |= DB_CREATE ;
788
789#ifdef O_NONBLOCK
790 if ((flags & O_NONBLOCK) == O_NONBLOCK)
791 Flags |= DB_EXCL ;
792#endif
793
794#if O_RDONLY == 0
795 if (flags == O_RDONLY)
796#else
797 if (flags & O_RDONLY) == O_RDONLY)
798#endif
799 Flags |= DB_RDONLY ;
800
801#ifdef O_NONBLOCK
802 if ((flags & O_TRUNC) == O_TRUNC)
803 Flags |= DB_TRUNCATE ;
804#endif
805
806 status = db_open(name, RETVAL->type, Flags, mode, NULL, openinfo, &RETVAL->dbp) ;
807 if (status == 0)
808 status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor) ;
809
810 if (status)
811 RETVAL->dbp = NULL ;
812
813 }
814#else
88108326 815 RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ;
1f70e1ea 816#endif
a0d0e21e 817
818 return (RETVAL) ;
819}
820
821
822static int
823not_here(s)
824char *s;
825{
826 croak("DB_File::%s not implemented on this architecture", s);
827 return -1;
828}
829
830static double
831constant(name, arg)
832char *name;
833int arg;
834{
835 errno = 0;
836 switch (*name) {
837 case 'A':
838 break;
839 case 'B':
840 if (strEQ(name, "BTREEMAGIC"))
841#ifdef BTREEMAGIC
842 return BTREEMAGIC;
843#else
844 goto not_there;
845#endif
846 if (strEQ(name, "BTREEVERSION"))
847#ifdef BTREEVERSION
848 return BTREEVERSION;
849#else
850 goto not_there;
851#endif
852 break;
853 case 'C':
854 break;
855 case 'D':
856 if (strEQ(name, "DB_LOCK"))
857#ifdef DB_LOCK
858 return DB_LOCK;
859#else
860 goto not_there;
861#endif
862 if (strEQ(name, "DB_SHMEM"))
863#ifdef DB_SHMEM
864 return DB_SHMEM;
865#else
866 goto not_there;
867#endif
868 if (strEQ(name, "DB_TXN"))
869#ifdef DB_TXN
870 return (U32)DB_TXN;
871#else
872 goto not_there;
873#endif
874 break;
875 case 'E':
876 break;
877 case 'F':
878 break;
879 case 'G':
880 break;
881 case 'H':
882 if (strEQ(name, "HASHMAGIC"))
883#ifdef HASHMAGIC
884 return HASHMAGIC;
885#else
886 goto not_there;
887#endif
888 if (strEQ(name, "HASHVERSION"))
889#ifdef HASHVERSION
890 return HASHVERSION;
891#else
892 goto not_there;
893#endif
894 break;
895 case 'I':
896 break;
897 case 'J':
898 break;
899 case 'K':
900 break;
901 case 'L':
902 break;
903 case 'M':
904 if (strEQ(name, "MAX_PAGE_NUMBER"))
905#ifdef MAX_PAGE_NUMBER
906 return (U32)MAX_PAGE_NUMBER;
907#else
908 goto not_there;
909#endif
910 if (strEQ(name, "MAX_PAGE_OFFSET"))
911#ifdef MAX_PAGE_OFFSET
912 return MAX_PAGE_OFFSET;
913#else
914 goto not_there;
915#endif
916 if (strEQ(name, "MAX_REC_NUMBER"))
917#ifdef MAX_REC_NUMBER
918 return (U32)MAX_REC_NUMBER;
919#else
920 goto not_there;
921#endif
922 break;
923 case 'N':
924 break;
925 case 'O':
926 break;
927 case 'P':
928 break;
929 case 'Q':
930 break;
931 case 'R':
932 if (strEQ(name, "RET_ERROR"))
933#ifdef RET_ERROR
934 return RET_ERROR;
935#else
936 goto not_there;
937#endif
938 if (strEQ(name, "RET_SPECIAL"))
939#ifdef RET_SPECIAL
940 return RET_SPECIAL;
941#else
942 goto not_there;
943#endif
944 if (strEQ(name, "RET_SUCCESS"))
945#ifdef RET_SUCCESS
946 return RET_SUCCESS;
947#else
948 goto not_there;
949#endif
950 if (strEQ(name, "R_CURSOR"))
951#ifdef R_CURSOR
952 return R_CURSOR;
953#else
954 goto not_there;
955#endif
956 if (strEQ(name, "R_DUP"))
957#ifdef R_DUP
958 return R_DUP;
959#else
960 goto not_there;
961#endif
962 if (strEQ(name, "R_FIRST"))
963#ifdef R_FIRST
964 return R_FIRST;
965#else
966 goto not_there;
967#endif
968 if (strEQ(name, "R_FIXEDLEN"))
969#ifdef R_FIXEDLEN
970 return R_FIXEDLEN;
971#else
972 goto not_there;
973#endif
974 if (strEQ(name, "R_IAFTER"))
975#ifdef R_IAFTER
976 return R_IAFTER;
977#else
978 goto not_there;
979#endif
980 if (strEQ(name, "R_IBEFORE"))
981#ifdef R_IBEFORE
982 return R_IBEFORE;
983#else
984 goto not_there;
985#endif
986 if (strEQ(name, "R_LAST"))
987#ifdef R_LAST
988 return R_LAST;
989#else
990 goto not_there;
991#endif
992 if (strEQ(name, "R_NEXT"))
993#ifdef R_NEXT
994 return R_NEXT;
995#else
996 goto not_there;
997#endif
998 if (strEQ(name, "R_NOKEY"))
999#ifdef R_NOKEY
1000 return R_NOKEY;
1001#else
1002 goto not_there;
1003#endif
1004 if (strEQ(name, "R_NOOVERWRITE"))
1005#ifdef R_NOOVERWRITE
1006 return R_NOOVERWRITE;
1007#else
1008 goto not_there;
1009#endif
1010 if (strEQ(name, "R_PREV"))
1011#ifdef R_PREV
1012 return R_PREV;
1013#else
1014 goto not_there;
1015#endif
1016 if (strEQ(name, "R_RECNOSYNC"))
1017#ifdef R_RECNOSYNC
1018 return R_RECNOSYNC;
1019#else
1020 goto not_there;
1021#endif
1022 if (strEQ(name, "R_SETCURSOR"))
1023#ifdef R_SETCURSOR
1024 return R_SETCURSOR;
1025#else
1026 goto not_there;
1027#endif
1028 if (strEQ(name, "R_SNAPSHOT"))
1029#ifdef R_SNAPSHOT
1030 return R_SNAPSHOT;
1031#else
1032 goto not_there;
1033#endif
1034 break;
1035 case 'S':
1036 break;
1037 case 'T':
1038 break;
1039 case 'U':
1040 break;
1041 case 'V':
1042 break;
1043 case 'W':
1044 break;
1045 case 'X':
1046 break;
1047 case 'Y':
1048 break;
1049 case 'Z':
1050 break;
1051 case '_':
a0d0e21e 1052 break;
1053 }
1054 errno = EINVAL;
1055 return 0;
1056
1057not_there:
1058 errno = ENOENT;
1059 return 0;
1060}
1061
1062MODULE = DB_File PACKAGE = DB_File PREFIX = db_
1063
1f70e1ea 1064BOOT:
1065 {
1066 GetVersionInfo() ;
1067
1068 empty.data = &zero ;
1069 empty.size = sizeof(recno_t) ;
1070 DBT_flags(empty) ;
1071 }
1072
a0d0e21e 1073double
1074constant(name,arg)
1075 char * name
1076 int arg
1077
1078
1079DB_File
05475680 1080db_DoTie_(isHASH, dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0666, type=DB_HASH)
1081 int isHASH
a0d0e21e 1082 char * dbtype
1083 int flags
1084 int mode
1085 CODE:
1086 {
1087 char * name = (char *) NULL ;
1088 SV * sv = (SV *) NULL ;
1089
05475680 1090 if (items >= 3 && SvOK(ST(2)))
1091 name = (char*) SvPV(ST(2), na) ;
a0d0e21e 1092
05475680 1093 if (items == 6)
1094 sv = ST(5) ;
a0d0e21e 1095
05475680 1096 RETVAL = ParseOpenInfo(isHASH, name, flags, mode, sv) ;
4633a7c4 1097 if (RETVAL->dbp == NULL)
1098 RETVAL = NULL ;
a0d0e21e 1099 }
1100 OUTPUT:
1101 RETVAL
1102
a0d0e21e 1103int
1104db_DESTROY(db)
1105 DB_File db
8e07c86e 1106 INIT:
1107 CurrentDB = db ;
1108 CLEANUP:
1109 if (db->hash)
1110 SvREFCNT_dec(db->hash) ;
1111 if (db->compare)
1112 SvREFCNT_dec(db->compare) ;
1113 if (db->prefix)
1114 SvREFCNT_dec(db->prefix) ;
1115 Safefree(db) ;
1f70e1ea 1116#ifdef DB_VERSION_MAJOR
1117 if (RETVAL > 0)
1118 RETVAL = -1 ;
1119#endif
a0d0e21e 1120
1121
1122int
1123db_DELETE(db, key, flags=0)
1124 DB_File db
1125 DBTKEY key
1126 u_int flags
8e07c86e 1127 INIT:
1128 CurrentDB = db ;
a0d0e21e 1129
f6b705ef 1130
1131int
1132db_EXISTS(db, key)
1133 DB_File db
1134 DBTKEY key
1135 CODE:
1136 {
1137 DBT value ;
1138
1f70e1ea 1139 DBT_flags(value) ;
f6b705ef 1140 CurrentDB = db ;
1f70e1ea 1141 RETVAL = (((db->dbp)->get)(db->dbp, TXN &key, &value, 0) == 0) ;
f6b705ef 1142 }
1143 OUTPUT:
1144 RETVAL
1145
a0d0e21e 1146int
1147db_FETCH(db, key, flags=0)
1148 DB_File db
1149 DBTKEY key
1150 u_int flags
1151 CODE:
1152 {
1f70e1ea 1153 DBT value ;
a0d0e21e 1154
1f70e1ea 1155 DBT_flags(value) ;
8e07c86e 1156 CurrentDB = db ;
1f70e1ea 1157 /* RETVAL = ((db->dbp)->get)(db->dbp, TXN &key, &value, flags) ; */
1158 RETVAL = db_get(db, key, value, flags) ;
a0d0e21e 1159 ST(0) = sv_newmortal();
1f70e1ea 1160 if (RETVAL == 0)
a0d0e21e 1161 sv_setpvn(ST(0), value.data, value.size);
1162 }
1163
1164int
1165db_STORE(db, key, value, flags=0)
1166 DB_File db
1167 DBTKEY key
1168 DBT value
1169 u_int flags
8e07c86e 1170 INIT:
1171 CurrentDB = db ;
a0d0e21e 1172
1173
1174int
1175db_FIRSTKEY(db)
1176 DB_File db
1177 CODE:
1178 {
1f70e1ea 1179 DBTKEY key ;
a0d0e21e 1180 DBT value ;
4633a7c4 1181 DB * Db = db->dbp ;
a0d0e21e 1182
1f70e1ea 1183 DBT_flags(key) ;
1184 DBT_flags(value) ;
8e07c86e 1185 CurrentDB = db ;
1f70e1ea 1186 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
a0d0e21e 1187 ST(0) = sv_newmortal();
1188 if (RETVAL == 0)
1189 {
05475680 1190 if (db->type != DB_RECNO)
a0d0e21e 1191 sv_setpvn(ST(0), key.data, key.size);
1192 else
1193 sv_setiv(ST(0), (I32)*(I32*)key.data - 1);
1194 }
1195 }
1196
1197int
1198db_NEXTKEY(db, key)
1199 DB_File db
1200 DBTKEY key
1201 CODE:
1202 {
1203 DBT value ;
4633a7c4 1204 DB * Db = db->dbp ;
a0d0e21e 1205
1f70e1ea 1206 DBT_flags(value) ;
8e07c86e 1207 CurrentDB = db ;
1f70e1ea 1208 RETVAL = do_SEQ(db, key, value, R_NEXT) ;
a0d0e21e 1209 ST(0) = sv_newmortal();
1210 if (RETVAL == 0)
1211 {
05475680 1212 if (db->type != DB_RECNO)
a0d0e21e 1213 sv_setpvn(ST(0), key.data, key.size);
1214 else
1215 sv_setiv(ST(0), (I32)*(I32*)key.data - 1);
1216 }
1217 }
1218
1219#
1220# These would be nice for RECNO
1221#
1222
1223int
1224unshift(db, ...)
1225 DB_File db
1226 CODE:
1227 {
1228 DBTKEY key ;
1229 DBT value ;
1230 int i ;
1231 int One ;
4633a7c4 1232 DB * Db = db->dbp ;
a0d0e21e 1233
1f70e1ea 1234 DBT_flags(key) ;
1235 DBT_flags(value) ;
8e07c86e 1236 CurrentDB = db ;
1f70e1ea 1237#ifdef DB_VERSION_MAJOR
1238 /* get the first value */
1239 RETVAL = do_SEQ(db, key, value, DB_FIRST) ;
1240 RETVAL = 0 ;
1241#else
a0d0e21e 1242 RETVAL = -1 ;
1f70e1ea 1243#endif
a0d0e21e 1244 for (i = items-1 ; i > 0 ; --i)
1245 {
1246 value.data = SvPV(ST(i), na) ;
1247 value.size = na ;
1248 One = 1 ;
1249 key.data = &One ;
1250 key.size = sizeof(int) ;
1f70e1ea 1251#ifdef DB_VERSION_MAJOR
1252 RETVAL = (db->cursor->c_put)(db->cursor, &key, &value, DB_BEFORE) ;
1253#else
4633a7c4 1254 RETVAL = (Db->put)(Db, &key, &value, R_IBEFORE) ;
1f70e1ea 1255#endif
a0d0e21e 1256 if (RETVAL != 0)
1257 break;
1258 }
1259 }
1260 OUTPUT:
1261 RETVAL
1262
1263I32
1264pop(db)
1265 DB_File db
1266 CODE:
1267 {
1268 DBTKEY key ;
1269 DBT value ;
4633a7c4 1270 DB * Db = db->dbp ;
a0d0e21e 1271
1f70e1ea 1272 DBT_flags(key) ;
1273 DBT_flags(value) ;
8e07c86e 1274 CurrentDB = db ;
1f70e1ea 1275
a0d0e21e 1276 /* First get the final value */
1f70e1ea 1277 RETVAL = do_SEQ(db, key, value, R_LAST) ;
a0d0e21e 1278 ST(0) = sv_newmortal();
1279 /* Now delete it */
1280 if (RETVAL == 0)
1281 {
f6b705ef 1282 /* the call to del will trash value, so take a copy now */
1283 sv_setpvn(ST(0), value.data, value.size);
1f70e1ea 1284 RETVAL = db_del(db, key, R_CURSOR) ;
f6b705ef 1285 if (RETVAL != 0)
1286 sv_setsv(ST(0), &sv_undef);
a0d0e21e 1287 }
1288 }
1289
1290I32
1291shift(db)
1292 DB_File db
1293 CODE:
1294 {
a0d0e21e 1295 DBT value ;
f6b705ef 1296 DBTKEY key ;
4633a7c4 1297 DB * Db = db->dbp ;
a0d0e21e 1298
1f70e1ea 1299 DBT_flags(key) ;
1300 DBT_flags(value) ;
8e07c86e 1301 CurrentDB = db ;
a0d0e21e 1302 /* get the first value */
1f70e1ea 1303 RETVAL = do_SEQ(db, key, value, R_FIRST) ;
a0d0e21e 1304 ST(0) = sv_newmortal();
1305 /* Now delete it */
1306 if (RETVAL == 0)
1307 {
f6b705ef 1308 /* the call to del will trash value, so take a copy now */
1309 sv_setpvn(ST(0), value.data, value.size);
1f70e1ea 1310 RETVAL = db_del(db, key, R_CURSOR) ;
f6b705ef 1311 if (RETVAL != 0)
1312 sv_setsv (ST(0), &sv_undef) ;
a0d0e21e 1313 }
1314 }
1315
1316
1317I32
1318push(db, ...)
1319 DB_File db
1320 CODE:
1321 {
1322 DBTKEY key ;
8e07c86e 1323 DBTKEY * keyptr = &key ;
a0d0e21e 1324 DBT value ;
4633a7c4 1325 DB * Db = db->dbp ;
a0d0e21e 1326 int i ;
1327
1f70e1ea 1328 DBT_flags(key) ;
1329 DBT_flags(value) ;
8e07c86e 1330 CurrentDB = db ;
a0d0e21e 1331 /* Set the Cursor to the Last element */
1f70e1ea 1332 RETVAL = do_SEQ(db, key, value, R_LAST) ;
8e07c86e 1333 if (RETVAL >= 0)
a0d0e21e 1334 {
8e07c86e 1335 if (RETVAL == 1)
1336 keyptr = &empty ;
1f70e1ea 1337#ifdef DB_VERSION_MAJOR
1338 for (i = 1 ; i < items ; ++i)
1339 {
1340
1341 ++ (* (int*)key.data) ;
1342 value.data = SvPV(ST(i), na) ;
1343 value.size = na ;
1344 RETVAL = (Db->put)(Db, NULL, &key, &value, 0) ;
1345 if (RETVAL != 0)
1346 break;
1347 }
1348#else
8e07c86e 1349 for (i = items - 1 ; i > 0 ; --i)
1350 {
1351 value.data = SvPV(ST(i), na) ;
1352 value.size = na ;
4633a7c4 1353 RETVAL = (Db->put)(Db, keyptr, &value, R_IAFTER) ;
8e07c86e 1354 if (RETVAL != 0)
1355 break;
1356 }
1f70e1ea 1357#endif
a0d0e21e 1358 }
1359 }
1360 OUTPUT:
1361 RETVAL
1362
1363
1364I32
1365length(db)
1366 DB_File db
1367 CODE:
8e07c86e 1368 CurrentDB = db ;
1f70e1ea 1369 RETVAL = GetArrayLength(db) ;
a0d0e21e 1370 OUTPUT:
1371 RETVAL
1372
1373
1374#
1375# Now provide an interface to the rest of the DB functionality
1376#
1377
1378int
1379db_del(db, key, flags=0)
1380 DB_File db
1381 DBTKEY key
1382 u_int flags
1f70e1ea 1383 CODE:
8e07c86e 1384 CurrentDB = db ;
1f70e1ea 1385 RETVAL = db_del(db, key, flags) ;
1386#ifdef DB_VERSION_MAJOR
1387 if (RETVAL > 0)
1388 RETVAL = -1 ;
1389 else if (RETVAL == DB_NOTFOUND)
1390 RETVAL = 1 ;
1391#endif
1392 OUTPUT:
1393 RETVAL
a0d0e21e 1394
1395
1396int
1397db_get(db, key, value, flags=0)
1398 DB_File db
1399 DBTKEY key
a6ed719b 1400 DBT value = NO_INIT
a0d0e21e 1401 u_int flags
1f70e1ea 1402 CODE:
8e07c86e 1403 CurrentDB = db ;
1f70e1ea 1404 DBT_flags(value) ;
1405 RETVAL = db_get(db, key, value, flags) ;
1406#ifdef DB_VERSION_MAJOR
1407 if (RETVAL > 0)
1408 RETVAL = -1 ;
1409 else if (RETVAL == DB_NOTFOUND)
1410 RETVAL = 1 ;
1411#endif
a0d0e21e 1412 OUTPUT:
1f70e1ea 1413 RETVAL
a0d0e21e 1414 value
1415
1416int
1417db_put(db, key, value, flags=0)
1418 DB_File db
1419 DBTKEY key
1420 DBT value
1421 u_int flags
1f70e1ea 1422 CODE:
8e07c86e 1423 CurrentDB = db ;
1f70e1ea 1424 RETVAL = db_put(db, key, value, flags) ;
1425#ifdef DB_VERSION_MAJOR
1426 if (RETVAL > 0)
1427 RETVAL = -1 ;
1428 else if (RETVAL == DB_KEYEXIST)
1429 RETVAL = 1 ;
1430#endif
a0d0e21e 1431 OUTPUT:
1f70e1ea 1432 RETVAL
a0d0e21e 1433 key if (flags & (R_IAFTER|R_IBEFORE)) OutputKey(ST(1), key);
1434
1435int
1436db_fd(db)
1437 DB_File db
1f70e1ea 1438 int status = 0 ;
1439 CODE:
8e07c86e 1440 CurrentDB = db ;
1f70e1ea 1441#ifdef DB_VERSION_MAJOR
1442 RETVAL = -1 ;
1443 status = (db->in_memory
1444 ? -1
1445 : ((db->dbp)->fd)(db->dbp, &RETVAL) ) ;
1446 if (status != 0)
1447 RETVAL = -1 ;
1448#else
1449 RETVAL = (db->in_memory
1450 ? -1
1451 : ((db->dbp)->fd)(db->dbp) ) ;
1452#endif
1453 OUTPUT:
1454 RETVAL
a0d0e21e 1455
1456int
1457db_sync(db, flags=0)
1458 DB_File db
1459 u_int flags
1f70e1ea 1460 CODE:
8e07c86e 1461 CurrentDB = db ;
1f70e1ea 1462 RETVAL = db_sync(db, flags) ;
1463#ifdef DB_VERSION_MAJOR
1464 if (RETVAL > 0)
1465 RETVAL = -1 ;
1466#endif
1467 OUTPUT:
1468 RETVAL
a0d0e21e 1469
1470
1471int
1472db_seq(db, key, value, flags)
1473 DB_File db
1474 DBTKEY key
a6ed719b 1475 DBT value = NO_INIT
a0d0e21e 1476 u_int flags
1f70e1ea 1477 CODE:
8e07c86e 1478 CurrentDB = db ;
1f70e1ea 1479 DBT_flags(value) ;
1480 RETVAL = db_seq(db, key, value, flags);
1481#ifdef DB_VERSION_MAJOR
1482 if (RETVAL > 0)
1483 RETVAL = -1 ;
1484 else if (RETVAL == DB_NOTFOUND)
1485 RETVAL = 1 ;
1486#endif
a0d0e21e 1487 OUTPUT:
1f70e1ea 1488 RETVAL
a0d0e21e 1489 key
1490 value
610ab055 1491