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