~ubuntu-branches/ubuntu/maverick/evolution-data-server/maverick-proposed

« back to all changes in this revision

Viewing changes to libdb/perl/BerkeleyDB/BerkeleyDB.xs

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-05-17 17:02:06 UTC
  • mfrom: (1.1.79 upstream) (1.6.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20100517170206-4ufr52vwrhh26yh0
Tags: 2.30.1-1ubuntu1
* Merge from debian experimental. Remaining change:
  (LP: #42199, #229669, #173703, #360344, #508494)
  + debian/control:
    - add Vcs-Bzr tag
    - don't use libgnome
    - Use Breaks instead of Conflicts against evolution 2.25 and earlier.
  + debian/evolution-data-server.install,
    debian/patches/45_libcamel_providers_version.patch:
    - use the upstream versioning, not a Debian-specific one 
  + debian/libedata-book1.2-dev.install, debian/libebackend-1.2-dev.install,
    debian/libcamel1.2-dev.install, debian/libedataserverui1.2-dev.install:
    - install html documentation
  + debian/rules:
    - don't build documentation it's shipped with the tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 
3
 
 BerkeleyDB.xs -- Perl 5 interface to Berkeley DB version 2 & 3
4
 
 
5
 
 written by Paul Marquess <Paul.Marquess@btinternet.com>
6
 
 
7
 
 All comments/suggestions/problems are welcome
8
 
 
9
 
     Copyright (c) 1997-2002 Paul Marquess. All rights reserved.
10
 
     This program is free software; you can redistribute it and/or
11
 
     modify it under the same terms as Perl itself.
12
 
 
13
 
     Please refer to the COPYRIGHT section in
14
 
 
15
 
 Changes:
16
 
        0.01 -  First Alpha Release
17
 
        0.02 -
18
 
 
19
 
*/
20
 
 
21
 
 
22
 
 
23
 
#ifdef __cplusplus
24
 
extern "C" {
25
 
#endif
26
 
 
27
 
#define PERL_POLLUTE
28
 
#include "EXTERN.h"
29
 
#include "perl.h"
30
 
#include "XSUB.h"
31
 
#include "ppport.h"
32
 
 
33
 
 
34
 
/* XSUB.h defines a macro called abort                          */
35
 
/* This clashes with the txn abort method in Berkeley DB 4.x    */
36
 
/* This is a problem with ActivePerl (at least)                 */
37
 
 
38
 
#ifdef _WIN32
39
 
#  ifdef abort
40
 
#    undef abort
41
 
#  endif
42
 
#  ifdef fopen
43
 
#    undef fopen
44
 
#  endif
45
 
#  ifdef fclose
46
 
#    undef fclose
47
 
#  endif
48
 
#endif
49
 
 
50
 
/* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
51
 
 * shortly #included by the <db.h>) __attribute__ to the possibly
52
 
 * already defined __attribute__, for example by GNUC or by Perl. */
53
 
 
54
 
#undef __attribute__
55
 
 
56
 
#ifdef USE_PERLIO
57
 
#    define GetFILEptr(sv) PerlIO_findFILE(IoOFP(sv_2io(sv)))
58
 
#else
59
 
#    define GetFILEptr(sv) IoOFP(sv_2io(sv))
60
 
#endif
61
 
 
62
 
#include <db.h>
63
 
 
64
 
/* Check the version of Berkeley DB */
65
 
 
66
 
#ifndef DB_VERSION_MAJOR
67
 
#ifdef HASHMAGIC
68
 
#error db.h is from Berkeley DB 1.x - need at least Berkeley DB 2.6.4
69
 
#else
70
 
#error db.h is not for Berkeley DB at all.
71
 
#endif
72
 
#endif
73
 
 
74
 
#if (DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6) ||\
75
 
    (DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR == 6 && DB_VERSION_PATCH < 4)
76
 
#  error db.h is from Berkeley DB 2.0-2.5 - need at least Berkeley DB 2.6.4
77
 
#endif
78
 
 
79
 
 
80
 
#if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0)
81
 
#  define IS_DB_3_0_x
82
 
#endif
83
 
 
84
 
#if DB_VERSION_MAJOR >= 3
85
 
#  define AT_LEAST_DB_3
86
 
#endif
87
 
 
88
 
#if DB_VERSION_MAJOR > 3 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 1)
89
 
#  define AT_LEAST_DB_3_1
90
 
#endif
91
 
 
92
 
#if DB_VERSION_MAJOR > 3 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 2)
93
 
#  define AT_LEAST_DB_3_2
94
 
#endif
95
 
 
96
 
#if DB_VERSION_MAJOR > 3 || \
97
 
    (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR > 2) ||\
98
 
    (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 2 && DB_VERSION_PATCH >= 6)
99
 
#  define AT_LEAST_DB_3_2_6
100
 
#endif
101
 
 
102
 
#if DB_VERSION_MAJOR > 3 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 3)
103
 
#  define AT_LEAST_DB_3_3
104
 
#endif
105
 
 
106
 
#if DB_VERSION_MAJOR >= 4
107
 
#  define AT_LEAST_DB_4
108
 
#endif
109
 
 
110
 
#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
111
 
#  define AT_LEAST_DB_4_1
112
 
#endif
113
 
 
114
 
#ifdef __cplusplus
115
 
}
116
 
#endif
117
 
 
118
 
#define DBM_FILTERING
119
 
#define STRICT_CLOSE
120
 
/* #define ALLOW_RECNO_OFFSET */
121
 
/* #define TRACE */
122
 
 
123
 
#if DB_VERSION_MAJOR == 2 && ! defined(DB_LOCK_DEADLOCK)
124
 
#  define DB_LOCK_DEADLOCK      EAGAIN
125
 
#endif /* DB_VERSION_MAJOR == 2 */
126
 
 
127
 
#if DB_VERSION_MAJOR == 2
128
 
#  define DB_QUEUE              4
129
 
#endif /* DB_VERSION_MAJOR == 2 */
130
 
 
131
 
#ifdef AT_LEAST_DB_3_2
132
 
#    define DB_callback DB * db,
133
 
#else
134
 
#    define DB_callback
135
 
#endif
136
 
 
137
 
#if DB_VERSION_MAJOR > 2
138
 
typedef struct {
139
 
        int              db_lorder;
140
 
        size_t           db_cachesize;
141
 
        size_t           db_pagesize;
142
 
 
143
 
 
144
 
        void *(*db_malloc) __P((size_t));
145
 
        int (*dup_compare)
146
 
            __P((DB_callback const DBT *, const DBT *));
147
 
 
148
 
        u_int32_t        bt_maxkey;
149
 
        u_int32_t        bt_minkey;
150
 
        int (*bt_compare)
151
 
            __P((DB_callback const DBT *, const DBT *));
152
 
        size_t (*bt_prefix)
153
 
            __P((DB_callback const DBT *, const DBT *));
154
 
 
155
 
        u_int32_t        h_ffactor;
156
 
        u_int32_t        h_nelem;
157
 
        u_int32_t      (*h_hash)
158
 
            __P((DB_callback const void *, u_int32_t));
159
 
 
160
 
        int              re_pad;
161
 
        int              re_delim;
162
 
        u_int32_t        re_len;
163
 
        char            *re_source;
164
 
 
165
 
#define DB_DELIMITER            0x0001
166
 
#define DB_FIXEDLEN             0x0008
167
 
#define DB_PAD                  0x0010
168
 
        u_int32_t        flags;
169
 
        u_int32_t        q_extentsize;
170
 
} DB_INFO ;
171
 
 
172
 
#endif /* DB_VERSION_MAJOR > 2 */
173
 
 
174
 
typedef struct {
175
 
        int             Status ;
176
 
        /* char         ErrBuff[1000] ; */
177
 
        SV *            ErrPrefix ;
178
 
        FILE *          ErrHandle ;
179
 
        DB_ENV *        Env ;
180
 
        int             open_dbs ;
181
 
        int             TxnMgrStatus ;
182
 
        int             active ;
183
 
        bool            txn_enabled ;
184
 
        } BerkeleyDB_ENV_type ;
185
 
 
186
 
 
187
 
typedef struct {
188
 
        DBTYPE          type ;
189
 
        bool            recno_or_queue ;
190
 
        char *          filename ;
191
 
        BerkeleyDB_ENV_type * parent_env ;
192
 
        DB *            dbp ;
193
 
        SV *            compare ;
194
 
        bool            in_compare ;
195
 
        SV *            dup_compare ;
196
 
        bool            in_dup_compare ;
197
 
        SV *            prefix ;
198
 
        bool            in_prefix ;
199
 
        SV *            hash ;
200
 
        bool            in_hash ;
201
 
#ifdef AT_LEAST_DB_3_3
202
 
        SV *            associated ;
203
 
        bool            secondary_db ;
204
 
#endif
205
 
        int             Status ;
206
 
        DB_INFO *       info ;
207
 
        DBC *           cursor ;
208
 
        DB_TXN *        txn ;
209
 
        int             open_cursors ;
210
 
        u_int32_t       partial ;
211
 
        u_int32_t       dlen ;
212
 
        u_int32_t       doff ;
213
 
        int             active ;
214
 
#ifdef ALLOW_RECNO_OFFSET
215
 
        int             array_base ;
216
 
#endif
217
 
#ifdef DBM_FILTERING
218
 
        SV *    filter_fetch_key ;
219
 
        SV *    filter_store_key ;
220
 
        SV *    filter_fetch_value ;
221
 
        SV *    filter_store_value ;
222
 
        int     filtering ;
223
 
#endif
224
 
        } BerkeleyDB_type;
225
 
 
226
 
 
227
 
typedef struct {
228
 
        DBTYPE          type ;
229
 
        bool            recno_or_queue ;
230
 
        char *          filename ;
231
 
        DB *            dbp ;
232
 
        SV *            compare ;
233
 
        SV *            dup_compare ;
234
 
        SV *            prefix ;
235
 
        SV *            hash ;
236
 
#ifdef AT_LEAST_DB_3_3
237
 
        SV *            associated ;
238
 
        bool            secondary_db ;
239
 
#endif
240
 
        int             Status ;
241
 
        DB_INFO *       info ;
242
 
        DBC *           cursor ;
243
 
        DB_TXN *        txn ;
244
 
        BerkeleyDB_type *               parent_db ;
245
 
        u_int32_t       partial ;
246
 
        u_int32_t       dlen ;
247
 
        u_int32_t       doff ;
248
 
        int             active ;
249
 
#ifdef ALLOW_RECNO_OFFSET
250
 
        int             array_base ;
251
 
#endif
252
 
#ifdef DBM_FILTERING
253
 
        SV *    filter_fetch_key ;
254
 
        SV *    filter_store_key ;
255
 
        SV *    filter_fetch_value ;
256
 
        SV *    filter_store_value ;
257
 
        int     filtering ;
258
 
#endif
259
 
        } BerkeleyDB_Cursor_type;
260
 
 
261
 
typedef struct {
262
 
        BerkeleyDB_ENV_type *   env ;
263
 
        } BerkeleyDB_TxnMgr_type ;
264
 
 
265
 
#if 1
266
 
typedef struct {
267
 
        int             Status ;
268
 
        DB_TXN *        txn ;
269
 
        int             active ;
270
 
        } BerkeleyDB_Txn_type ;
271
 
#else
272
 
typedef DB_TXN                BerkeleyDB_Txn_type ;
273
 
#endif
274
 
 
275
 
typedef BerkeleyDB_ENV_type *   BerkeleyDB__Env ;
276
 
typedef BerkeleyDB_ENV_type *   BerkeleyDB__Env__Raw ;
277
 
typedef BerkeleyDB_ENV_type *   BerkeleyDB__Env__Inner ;
278
 
typedef BerkeleyDB_type *       BerkeleyDB ;
279
 
typedef void *                  BerkeleyDB__Raw ;
280
 
typedef BerkeleyDB_type *       BerkeleyDB__Common ;
281
 
typedef BerkeleyDB_type *       BerkeleyDB__Common__Raw ;
282
 
typedef BerkeleyDB_type *       BerkeleyDB__Common__Inner ;
283
 
typedef BerkeleyDB_type *       BerkeleyDB__Hash ;
284
 
typedef BerkeleyDB_type *       BerkeleyDB__Hash__Raw ;
285
 
typedef BerkeleyDB_type *       BerkeleyDB__Btree ;
286
 
typedef BerkeleyDB_type *       BerkeleyDB__Btree__Raw ;
287
 
typedef BerkeleyDB_type *       BerkeleyDB__Recno ;
288
 
typedef BerkeleyDB_type *       BerkeleyDB__Recno__Raw ;
289
 
typedef BerkeleyDB_type *       BerkeleyDB__Queue ;
290
 
typedef BerkeleyDB_type *       BerkeleyDB__Queue__Raw ;
291
 
typedef BerkeleyDB_Cursor_type          BerkeleyDB__Cursor_type ;
292
 
typedef BerkeleyDB_Cursor_type *        BerkeleyDB__Cursor ;
293
 
typedef BerkeleyDB_Cursor_type *        BerkeleyDB__Cursor__Raw ;
294
 
typedef BerkeleyDB_TxnMgr_type * BerkeleyDB__TxnMgr ;
295
 
typedef BerkeleyDB_TxnMgr_type * BerkeleyDB__TxnMgr__Raw ;
296
 
typedef BerkeleyDB_TxnMgr_type * BerkeleyDB__TxnMgr__Inner ;
297
 
typedef BerkeleyDB_Txn_type *   BerkeleyDB__Txn ;
298
 
typedef BerkeleyDB_Txn_type *   BerkeleyDB__Txn__Raw ;
299
 
typedef BerkeleyDB_Txn_type *   BerkeleyDB__Txn__Inner ;
300
 
#if 0
301
 
typedef DB_LOG *                BerkeleyDB__Log ;
302
 
typedef DB_LOCKTAB *            BerkeleyDB__Lock ;
303
 
#endif
304
 
typedef DBT                     DBTKEY ;
305
 
typedef DBT                     DBT_OPT ;
306
 
typedef DBT                     DBT_B ;
307
 
typedef DBT                     DBTKEY_B ;
308
 
typedef DBT                     DBTVALUE ;
309
 
typedef void *                  PV_or_NULL ;
310
 
typedef PerlIO *                IO_or_NULL ;
311
 
typedef int                     DualType ;
312
 
 
313
 
static void
314
 
hash_delete(char * hash, char * key);
315
 
 
316
 
#ifdef TRACE
317
 
#  define Trace(x)      printf x
318
 
#else
319
 
#  define Trace(x)
320
 
#endif
321
 
 
322
 
#ifdef ALLOW_RECNO_OFFSET
323
 
#  define RECNO_BASE    db->array_base
324
 
#else
325
 
#  define RECNO_BASE    1
326
 
#endif
327
 
 
328
 
#if DB_VERSION_MAJOR == 2
329
 
#  define flagSet_DB2(i, f) i |= f
330
 
#else
331
 
#  define flagSet_DB2(i, f)
332
 
#endif
333
 
 
334
 
#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
335
 
#  define flagSet(bitmask)        (flags & (bitmask))
336
 
#else
337
 
#  define flagSet(bitmask)      ((flags & DB_OPFLAGS_MASK) == (bitmask))
338
 
#endif
339
 
 
340
 
#if DB_VERSION_MAJOR == 2 
341
 
#  define BackRef       internal
342
 
#else
343
 
#  if DB_VERSION_MAJOR == 3 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 0)
344
 
#    define BackRef     cj_internal
345
 
#  else
346
 
#    define BackRef     api_internal
347
 
#  endif
348
 
#endif
349
 
 
350
 
#define ERR_BUFF "BerkeleyDB::Error"
351
 
 
352
 
#define ZMALLOC(to, typ) ((to = (typ *)safemalloc(sizeof(typ))), \
353
 
                                Zero(to,1,typ))
354
 
 
355
 
#define DBT_clear(x)    Zero(&x, 1, DBT) ;
356
 
 
357
 
#if 1
358
 
#define getInnerObject(x) (*av_fetch((AV*)SvRV(x), 0, FALSE))
359
 
#else
360
 
#define getInnerObject(x) ((SV*)SvRV(sv))
361
 
#endif
362
 
 
363
 
#define my_sv_setpvn(sv, d, s) (s ? sv_setpvn(sv, d, s) : sv_setpv(sv, "") )
364
 
 
365
 
#define SetValue_iv(i, k) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) \
366
 
                                i = SvIV(sv)
367
 
#define SetValue_io(i, k) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) \
368
 
                                i = GetFILEptr(sv)
369
 
#define SetValue_sv(i, k) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) \
370
 
                                i = sv
371
 
#define SetValue_pv(i, k,t) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) \
372
 
                                i = (t)SvPV(sv,PL_na)
373
 
#define SetValue_pvx(i, k, t) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) \
374
 
                                i = (t)SvPVX(sv)
375
 
#define SetValue_ov(i,k,t) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) {\
376
 
                                IV tmp = SvIV(getInnerObject(sv)) ;     \
377
 
                                i = INT2PTR(t, tmp) ;                   \
378
 
                          }
379
 
 
380
 
#define SetValue_ovx(i,k,t) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) {\
381
 
                                HV * hv = (HV *)GetInternalObject(sv);          \
382
 
                                SV ** svp = hv_fetch(hv, "db", 2, FALSE);\
383
 
                                IV tmp = SvIV(*svp);                    \
384
 
                                i = INT2PTR(t, tmp) ;                           \
385
 
                          }
386
 
 
387
 
#define SetValue_ovX(i,k,t) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) {\
388
 
                                IV tmp = SvIV(GetInternalObject(sv));\
389
 
                                i = INT2PTR(t, tmp) ;                           \
390
 
                          }
391
 
 
392
 
#define LastDBerror DB_RUNRECOVERY
393
 
 
394
 
#define setDUALerrno(var, err)                                  \
395
 
                sv_setnv(var, (double)err) ;                    \
396
 
                sv_setpv(var, ((err) ? db_strerror(err) : "")) ;\
397
 
                SvNOK_on(var);
398
 
 
399
 
#define OutputValue(arg, name)                                  \
400
 
        { if (RETVAL == 0) {                                    \
401
 
              my_sv_setpvn(arg, name.data, name.size) ;         \
402
 
              DBM_ckFilter(arg, filter_fetch_value,"filter_fetch_value") ;            \
403
 
          }                                                     \
404
 
        }
405
 
 
406
 
#define OutputValue_B(arg, name)                                  \
407
 
        { if (RETVAL == 0) {                                    \
408
 
                if (db->type == DB_BTREE &&                     \
409
 
                        flagSet(DB_GET_RECNO)){                 \
410
 
                    sv_setiv(arg, (I32)(*(I32*)name.data) - RECNO_BASE); \
411
 
                }                                               \
412
 
                else {                                          \
413
 
                    my_sv_setpvn(arg, name.data, name.size) ;   \
414
 
                }                                               \
415
 
                DBM_ckFilter(arg, filter_fetch_value, "filter_fetch_value");          \
416
 
          }                                                     \
417
 
        }
418
 
 
419
 
#define OutputKey(arg, name)                                    \
420
 
        { if (RETVAL == 0)                                      \
421
 
          {                                                     \
422
 
                if (!db->recno_or_queue) {                      \
423
 
                    my_sv_setpvn(arg, name.data, name.size);    \
424
 
                }                                               \
425
 
                else                                            \
426
 
                    sv_setiv(arg, (I32)*(I32*)name.data - RECNO_BASE);   \
427
 
                DBM_ckFilter(arg, filter_fetch_key, "filter_fetch_key") ;            \
428
 
          }                                                     \
429
 
        }
430
 
 
431
 
#define OutputKey_B(arg, name)                                  \
432
 
        { if (RETVAL == 0)                                      \
433
 
          {                                                     \
434
 
                if (db->recno_or_queue ||                       \
435
 
                        (db->type == DB_BTREE &&                \
436
 
                            flagSet(DB_GET_RECNO))){            \
437
 
                    sv_setiv(arg, (I32)(*(I32*)name.data) - RECNO_BASE); \
438
 
                }                                               \
439
 
                else {                                          \
440
 
                    my_sv_setpvn(arg, name.data, name.size);    \
441
 
                }                                               \
442
 
                DBM_ckFilter(arg, filter_fetch_key, "filter_fetch_key") ;            \
443
 
          }                                                     \
444
 
        }
445
 
 
446
 
#define SetPartial(data,db)                                     \
447
 
        data.flags = db->partial ;                              \
448
 
        data.dlen  = db->dlen ;                                 \
449
 
        data.doff  = db->doff ;
450
 
 
451
 
#define ckActive(active, type)                                  \
452
 
    {                                                           \
453
 
        if (!active)                                            \
454
 
            softCrash("%s is already closed", type) ;           \
455
 
    }
456
 
 
457
 
#define ckActive_Environment(a) ckActive(a, "Environment")
458
 
#define ckActive_TxnMgr(a)      ckActive(a, "Transaction Manager")
459
 
#define ckActive_Transaction(a) ckActive(a, "Transaction")
460
 
#define ckActive_Database(a)    ckActive(a, "Database")
461
 
#define ckActive_Cursor(a)      ckActive(a, "Cursor")
462
 
 
463
 
/* Internal Global Data */
464
 
static db_recno_t Value ;
465
 
static db_recno_t zero = 0 ;
466
 
static BerkeleyDB       CurrentDB ;
467
 
 
468
 
static DBTKEY   empty ;
469
 
#if 0
470
 
static char     ErrBuff[1000] ;
471
 
#endif
472
 
 
473
 
#ifdef AT_LEAST_DB_3_3
474
 
#    if PERL_REVISION == 5 && PERL_VERSION <= 4
475
 
 
476
 
/* saferealloc in perl5.004 will croak if it is given a NULL pointer*/
477
 
void *
478
 
MyRealloc(void * ptr, size_t size)
479
 
{
480
 
    if (ptr == NULL ) 
481
 
        return safemalloc(size) ; 
482
 
    else
483
 
        return saferealloc(ptr, size) ;
484
 
}
485
 
 
486
 
#    else
487
 
#        define MyRealloc saferealloc
488
 
#    endif
489
 
#endif
490
 
 
491
 
static char *
492
 
my_strdup(const char *s)
493
 
{
494
 
    if (s == NULL)
495
 
        return NULL ;
496
 
 
497
 
    {
498
 
        MEM_SIZE l = strlen(s);
499
 
        char *s1 = (char *)safemalloc(l);
500
 
 
501
 
        Copy(s, s1, (MEM_SIZE)l, char);
502
 
        return s1;
503
 
    }
504
 
}
505
 
 
506
 
#if DB_VERSION_MAJOR == 2
507
 
static char *
508
 
db_strerror(int err)
509
 
{
510
 
    if (err == 0)
511
 
        return "" ;
512
 
 
513
 
    if (err > 0)
514
 
        return Strerror(err) ;
515
 
 
516
 
    switch (err) {
517
 
        case DB_INCOMPLETE:
518
 
                return ("DB_INCOMPLETE: Sync was unable to complete");
519
 
        case DB_KEYEMPTY:
520
 
                return ("DB_KEYEMPTY: Non-existent key/data pair");
521
 
        case DB_KEYEXIST:
522
 
                return ("DB_KEYEXIST: Key/data pair already exists");
523
 
        case DB_LOCK_DEADLOCK:
524
 
                return (
525
 
                    "DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock");
526
 
        case DB_LOCK_NOTGRANTED:
527
 
                return ("DB_LOCK_NOTGRANTED: Lock not granted");
528
 
        case DB_LOCK_NOTHELD:
529
 
                return ("DB_LOCK_NOTHELD: Lock not held by locker");
530
 
        case DB_NOTFOUND:
531
 
                return ("DB_NOTFOUND: No matching key/data pair found");
532
 
        case DB_RUNRECOVERY:
533
 
                return ("DB_RUNRECOVERY: Fatal error, run database recovery");
534
 
        default:
535
 
                return "Unknown Error" ;
536
 
 
537
 
    }
538
 
}
539
 
#endif  /* DB_VERSION_MAJOR == 2 */
540
 
 
541
 
#ifdef TRACE
542
 
#if DB_VERSION_MAJOR > 2
543
 
static char *
544
 
my_db_strerror(int err)
545
 
{
546
 
    static char buffer[1000] ;
547
 
    SV * sv = perl_get_sv(ERR_BUFF, FALSE) ;
548
 
    sprintf(buffer, "%d: %s", err, db_strerror(err)) ;
549
 
    if (err && sv) {
550
 
        strcat(buffer, ", ") ;
551
 
        strcat(buffer, SvPVX(sv)) ;
552
 
    }
553
 
    return buffer;
554
 
}
555
 
#endif
556
 
#endif
557
 
 
558
 
static void
559
 
close_everything(void)
560
 
{
561
 
    dTHR;
562
 
    Trace(("close_everything\n")) ;
563
 
    /* Abort All Transactions */
564
 
    {
565
 
        BerkeleyDB__Txn__Raw    tid ;
566
 
        HE * he ;
567
 
        I32 len ;
568
 
        HV * hv = perl_get_hv("BerkeleyDB::Term::Txn", TRUE);
569
 
        int  all = 0 ;
570
 
        int  closed = 0 ;
571
 
        (void)hv_iterinit(hv) ;
572
 
        Trace(("BerkeleyDB::Term::close_all_txns dirty=%d\n", PL_dirty)) ;
573
 
        while ( (he = hv_iternext(hv)) ) {
574
 
            tid = * (BerkeleyDB__Txn__Raw *) hv_iterkey(he, &len) ;
575
 
            Trace(("  Aborting Transaction [%d] in [%d] Active [%d]\n", tid->txn, tid, tid->active));
576
 
            if (tid->active) {
577
 
#ifdef AT_LEAST_DB_4
578
 
            tid->txn->abort(tid->txn) ;
579
 
#else
580
 
                txn_abort(tid->txn);
581
 
#endif
582
 
                ++ closed ;
583
 
            }
584
 
            tid->active = FALSE ;
585
 
            ++ all ;
586
 
        }
587
 
        Trace(("End of BerkeleyDB::Term::close_all_txns aborted %d of %d transactios\n",closed, all)) ;
588
 
    }
589
 
 
590
 
    /* Close All Cursors */
591
 
    {
592
 
        BerkeleyDB__Cursor db ;
593
 
        HE * he ;
594
 
        I32 len ;
595
 
        HV * hv = perl_get_hv("BerkeleyDB::Term::Cursor", TRUE);
596
 
        int  all = 0 ;
597
 
        int  closed = 0 ;
598
 
        (void) hv_iterinit(hv) ;
599
 
        Trace(("BerkeleyDB::Term::close_all_cursors \n")) ;
600
 
        while ( (he = hv_iternext(hv)) ) {
601
 
            db = * (BerkeleyDB__Cursor*) hv_iterkey(he, &len) ;
602
 
            Trace(("  Closing Cursor [%d] in [%d] Active [%d]\n", db->cursor, db, db->active));
603
 
            if (db->active) {
604
 
                ((db->cursor)->c_close)(db->cursor) ;
605
 
                ++ closed ;
606
 
            }
607
 
            db->active = FALSE ;
608
 
            ++ all ;
609
 
        }
610
 
        Trace(("End of BerkeleyDB::Term::close_all_cursors closed %d of %d cursors\n",closed, all)) ;
611
 
    }
612
 
 
613
 
    /* Close All Databases */
614
 
    {
615
 
        BerkeleyDB db ;
616
 
        HE * he ;
617
 
        I32 len ;
618
 
        HV * hv = perl_get_hv("BerkeleyDB::Term::Db", TRUE);
619
 
        int  all = 0 ;
620
 
        int  closed = 0 ;
621
 
        (void)hv_iterinit(hv) ;
622
 
        Trace(("BerkeleyDB::Term::close_all_dbs\n" )) ;
623
 
        while ( (he = hv_iternext(hv)) ) {
624
 
            db = * (BerkeleyDB*) hv_iterkey(he, &len) ;
625
 
            Trace(("  Closing Database [%d] in [%d] Active [%d]\n", db->dbp, db, db->active));
626
 
            if (db->active) {
627
 
                (db->dbp->close)(db->dbp, 0) ;
628
 
                ++ closed ;
629
 
            }
630
 
            db->active = FALSE ;
631
 
            ++ all ;
632
 
        }
633
 
        Trace(("End of BerkeleyDB::Term::close_all_dbs closed %d of %d dbs\n",closed, all)) ;
634
 
    }
635
 
 
636
 
    /* Close All Environments */
637
 
    {
638
 
        BerkeleyDB__Env env ;
639
 
        HE * he ;
640
 
        I32 len ;
641
 
        HV * hv = perl_get_hv("BerkeleyDB::Term::Env", TRUE);
642
 
        int  all = 0 ;
643
 
        int  closed = 0 ;
644
 
        (void)hv_iterinit(hv) ;
645
 
        Trace(("BerkeleyDB::Term::close_all_envs\n")) ;
646
 
        while ( (he = hv_iternext(hv)) ) {
647
 
            env = * (BerkeleyDB__Env*) hv_iterkey(he, &len) ;
648
 
            Trace(("  Closing Environment [%d] in [%d] Active [%d]\n", env->Env, env, env->active));
649
 
            if (env->active) {
650
 
#if DB_VERSION_MAJOR == 2
651
 
                db_appexit(env->Env) ;
652
 
#else
653
 
                (env->Env->close)(env->Env, 0) ;
654
 
#endif
655
 
                ++ closed ;
656
 
            }
657
 
            env->active = FALSE ;
658
 
            ++ all ;
659
 
        }
660
 
        Trace(("End of BerkeleyDB::Term::close_all_envs closed %d of %d dbs\n",closed, all)) ;
661
 
    }
662
 
 
663
 
    Trace(("end close_everything\n")) ;
664
 
 
665
 
}
666
 
 
667
 
static void
668
 
destroyDB(BerkeleyDB db)
669
 
{
670
 
    dTHR;
671
 
    if (! PL_dirty && db->active) {
672
 
        -- db->open_cursors ;
673
 
        ((db->dbp)->close)(db->dbp, 0) ;
674
 
    }
675
 
    if (db->hash)
676
 
          SvREFCNT_dec(db->hash) ;
677
 
    if (db->compare)
678
 
          SvREFCNT_dec(db->compare) ;
679
 
    if (db->dup_compare)
680
 
          SvREFCNT_dec(db->dup_compare) ;
681
 
#ifdef AT_LEAST_DB_3_3
682
 
    if (db->associated && !db->secondary_db)
683
 
          SvREFCNT_dec(db->associated) ;
684
 
#endif
685
 
    if (db->prefix)
686
 
          SvREFCNT_dec(db->prefix) ;
687
 
#ifdef DBM_FILTERING
688
 
    if (db->filter_fetch_key)
689
 
          SvREFCNT_dec(db->filter_fetch_key) ;
690
 
    if (db->filter_store_key)
691
 
          SvREFCNT_dec(db->filter_store_key) ;
692
 
    if (db->filter_fetch_value)
693
 
          SvREFCNT_dec(db->filter_fetch_value) ;
694
 
    if (db->filter_store_value)
695
 
          SvREFCNT_dec(db->filter_store_value) ;
696
 
#endif
697
 
    hash_delete("BerkeleyDB::Term::Db", (char *)db) ;
698
 
    if (db->filename)
699
 
             Safefree(db->filename) ;
700
 
    Safefree(db) ;
701
 
}
702
 
 
703
 
static int
704
 
softCrash(const char *pat, ...)
705
 
{
706
 
    char buffer1 [500] ;
707
 
    char buffer2 [500] ;
708
 
    va_list args;
709
 
    va_start(args, pat);
710
 
 
711
 
    Trace(("softCrash: %s\n", pat)) ;
712
 
 
713
 
#define ABORT_PREFIX "BerkeleyDB Aborting: "
714
 
 
715
 
    /* buffer = (char*) safemalloc(strlen(pat) + strlen(ABORT_PREFIX) + 1) ; */
716
 
    strcpy(buffer1, ABORT_PREFIX) ;
717
 
    strcat(buffer1, pat) ;
718
 
 
719
 
    vsprintf(buffer2, buffer1, args) ;
720
 
 
721
 
    croak(buffer2);
722
 
 
723
 
    /* NOTREACHED */
724
 
    va_end(args);
725
 
    return 1 ;
726
 
}
727
 
 
728
 
 
729
 
static I32
730
 
GetArrayLength(BerkeleyDB db)
731
 
{
732
 
    DBT         key ;
733
 
    DBT         value ;
734
 
    int         RETVAL = 0 ;
735
 
    DBC *       cursor ;
736
 
 
737
 
    DBT_clear(key) ;
738
 
    DBT_clear(value) ;
739
 
#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
740
 
    if ( ((db->dbp)->cursor)(db->dbp, db->txn, &cursor) == 0 )
741
 
#else
742
 
    if ( ((db->dbp)->cursor)(db->dbp, db->txn, &cursor, 0) == 0 )
743
 
#endif
744
 
    {
745
 
        RETVAL = cursor->c_get(cursor, &key, &value, DB_LAST) ;
746
 
        if (RETVAL == 0)
747
 
            RETVAL = *(I32 *)key.data ;
748
 
        else /* No key means empty file */
749
 
            RETVAL = 0 ;
750
 
        cursor->c_close(cursor) ;
751
 
    }
752
 
 
753
 
    Trace(("GetArrayLength got %d\n", RETVAL)) ;
754
 
    return ((I32)RETVAL) ;
755
 
}
756
 
 
757
 
#if 0
758
 
 
759
 
#define GetRecnoKey(db, value)  _GetRecnoKey(db, value)
760
 
 
761
 
static db_recno_t
762
 
_GetRecnoKey(BerkeleyDB db, I32 value)
763
 
{
764
 
    Trace(("GetRecnoKey start value = %d\n", value)) ;
765
 
    if (db->recno_or_queue && value < 0) {
766
 
        /* Get the length of the array */
767
 
        I32 length = GetArrayLength(db) ;
768
 
 
769
 
        /* check for attempt to write before start of array */
770
 
        if (length + value + RECNO_BASE <= 0)
771
 
            softCrash("Modification of non-creatable array value attempted, subscript %ld", (long)value) ;
772
 
 
773
 
        value = length + value + RECNO_BASE ;
774
 
    }
775
 
    else
776
 
        ++ value ;
777
 
 
778
 
    Trace(("GetRecnoKey end value = %d\n", value)) ;
779
 
 
780
 
    return value ;
781
 
}
782
 
 
783
 
#else /* ! 0 */
784
 
 
785
 
#if 0
786
 
#ifdef ALLOW_RECNO_OFFSET
787
 
#define GetRecnoKey(db, value) _GetRecnoKey(db, value)
788
 
 
789
 
static db_recno_t
790
 
_GetRecnoKey(BerkeleyDB db, I32 value)
791
 
{
792
 
    if (value + RECNO_BASE < 1)
793
 
        softCrash("key value %d < base (%d)", (value), RECNO_BASE?0:1) ;
794
 
    return value + RECNO_BASE ;
795
 
}
796
 
 
797
 
#else
798
 
#endif /* ALLOW_RECNO_OFFSET */
799
 
#endif /* 0 */
800
 
 
801
 
#define GetRecnoKey(db, value) ((value) + RECNO_BASE )
802
 
 
803
 
#endif /* 0 */
804
 
 
805
 
#if 0
806
 
static SV *
807
 
GetInternalObject(SV * sv)
808
 
{
809
 
    SV * info = (SV*) NULL ;
810
 
    SV * s ;
811
 
    MAGIC * mg ;
812
 
 
813
 
    Trace(("in GetInternalObject %d\n", sv)) ;
814
 
    if (sv == NULL || !SvROK(sv))
815
 
        return NULL ;
816
 
 
817
 
    s = SvRV(sv) ;
818
 
    if (SvMAGICAL(s))
819
 
    {
820
 
        if (SvTYPE(s) == SVt_PVHV || SvTYPE(s) == SVt_PVAV)
821
 
            mg = mg_find(s, 'P') ;
822
 
        else
823
 
            mg = mg_find(s, 'q') ;
824
 
 
825
 
         /* all this testing is probably overkill, but till I know more
826
 
            about global destruction it stays.
827
 
         */
828
 
        /* if (mg && mg->mg_obj && SvRV(mg->mg_obj) && SvPVX(SvRV(mg->mg_obj))) */
829
 
        if (mg && mg->mg_obj && SvRV(mg->mg_obj) )
830
 
            info = SvRV(mg->mg_obj) ;
831
 
        else
832
 
            info = s ;
833
 
    }
834
 
 
835
 
    Trace(("end of GetInternalObject %d\n", info)) ;
836
 
    return info ;
837
 
}
838
 
#endif
839
 
 
840
 
static int
841
 
btree_compare(DB_callback const DBT * key1, const DBT * key2 )
842
 
{
843
 
    dSP ;
844
 
    char * data1, * data2 ;
845
 
    int retval ;
846
 
    int count ;
847
 
    BerkeleyDB  keepDB = CurrentDB ;
848
 
 
849
 
    data1 = (char*) key1->data ;
850
 
    data2 = (char*) key2->data ;
851
 
 
852
 
#ifndef newSVpvn
853
 
    /* As newSVpv will assume that the data pointer is a null terminated C
854
 
       string if the size parameter is 0, make sure that data points to an
855
 
       empty string if the length is 0
856
 
    */
857
 
    if (key1->size == 0)
858
 
        data1 = "" ;
859
 
    if (key2->size == 0)
860
 
        data2 = "" ;
861
 
#endif
862
 
 
863
 
    ENTER ;
864
 
    SAVETMPS;
865
 
 
866
 
    PUSHMARK(SP) ;
867
 
    EXTEND(SP,2) ;
868
 
    PUSHs(sv_2mortal(newSVpvn(data1,key1->size)));
869
 
    PUSHs(sv_2mortal(newSVpvn(data2,key2->size)));
870
 
    PUTBACK ;
871
 
 
872
 
    count = perl_call_sv(CurrentDB->compare, G_SCALAR);
873
 
 
874
 
    SPAGAIN ;
875
 
 
876
 
    if (count != 1)
877
 
        softCrash ("in btree_compare - expected 1 return value from compare sub, got %d", count) ;
878
 
 
879
 
    retval = POPi ;
880
 
 
881
 
    PUTBACK ;
882
 
    FREETMPS ;
883
 
    LEAVE ;
884
 
    CurrentDB = keepDB ;
885
 
    return (retval) ;
886
 
 
887
 
}
888
 
 
889
 
static int
890
 
dup_compare(DB_callback const DBT * key1, const DBT * key2 )
891
 
{
892
 
    dSP ;
893
 
    char * data1, * data2 ;
894
 
    int retval ;
895
 
    int count ;
896
 
    BerkeleyDB  keepDB = CurrentDB ;
897
 
 
898
 
    Trace(("In dup_compare \n")) ;
899
 
    if (!CurrentDB)
900
 
        softCrash("Internal Error - No CurrentDB in dup_compare") ;
901
 
    if (CurrentDB->dup_compare == NULL)
902
 
        softCrash("in dup_compare: no callback specified for database '%s'", CurrentDB->filename) ;
903
 
 
904
 
    data1 = (char*) key1->data ;
905
 
    data2 = (char*) key2->data ;
906
 
 
907
 
#ifndef newSVpvn
908
 
    /* As newSVpv will assume that the data pointer is a null terminated C
909
 
       string if the size parameter is 0, make sure that data points to an
910
 
       empty string if the length is 0
911
 
    */
912
 
    if (key1->size == 0)
913
 
        data1 = "" ;
914
 
    if (key2->size == 0)
915
 
        data2 = "" ;
916
 
#endif
917
 
 
918
 
    ENTER ;
919
 
    SAVETMPS;
920
 
 
921
 
    PUSHMARK(SP) ;
922
 
    EXTEND(SP,2) ;
923
 
    PUSHs(sv_2mortal(newSVpvn(data1,key1->size)));
924
 
    PUSHs(sv_2mortal(newSVpvn(data2,key2->size)));
925
 
    PUTBACK ;
926
 
 
927
 
    count = perl_call_sv(CurrentDB->dup_compare, G_SCALAR);
928
 
 
929
 
    SPAGAIN ;
930
 
 
931
 
    if (count != 1)
932
 
        softCrash ("dup_compare: expected 1 return value from compare sub, got %d", count) ;
933
 
 
934
 
    retval = POPi ;
935
 
 
936
 
    PUTBACK ;
937
 
    FREETMPS ;
938
 
    LEAVE ;
939
 
    CurrentDB = keepDB ;
940
 
    return (retval) ;
941
 
 
942
 
}
943
 
 
944
 
static size_t
945
 
btree_prefix(DB_callback const DBT * key1, const DBT * key2 )
946
 
{
947
 
    dSP ;
948
 
    char * data1, * data2 ;
949
 
    int retval ;
950
 
    int count ;
951
 
    BerkeleyDB  keepDB = CurrentDB ;
952
 
 
953
 
    data1 = (char*) key1->data ;
954
 
    data2 = (char*) key2->data ;
955
 
 
956
 
#ifndef newSVpvn
957
 
    /* As newSVpv will assume that the data pointer is a null terminated C
958
 
       string if the size parameter is 0, make sure that data points to an
959
 
       empty string if the length is 0
960
 
    */
961
 
    if (key1->size == 0)
962
 
        data1 = "" ;
963
 
    if (key2->size == 0)
964
 
        data2 = "" ;
965
 
#endif
966
 
 
967
 
    ENTER ;
968
 
    SAVETMPS;
969
 
 
970
 
    PUSHMARK(SP) ;
971
 
    EXTEND(SP,2) ;
972
 
    PUSHs(sv_2mortal(newSVpvn(data1,key1->size)));
973
 
    PUSHs(sv_2mortal(newSVpvn(data2,key2->size)));
974
 
    PUTBACK ;
975
 
 
976
 
    count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
977
 
 
978
 
    SPAGAIN ;
979
 
 
980
 
    if (count != 1)
981
 
        softCrash ("btree_prefix: expected 1 return value from prefix sub, got %d", count) ;
982
 
 
983
 
    retval = POPi ;
984
 
 
985
 
    PUTBACK ;
986
 
    FREETMPS ;
987
 
    LEAVE ;
988
 
    CurrentDB = keepDB ;
989
 
 
990
 
    return (retval) ;
991
 
}
992
 
 
993
 
static u_int32_t
994
 
hash_cb(DB_callback const void * data, u_int32_t size)
995
 
{
996
 
    dSP ;
997
 
    int retval ;
998
 
    int count ;
999
 
    BerkeleyDB  keepDB = CurrentDB ;
1000
 
 
1001
 
#ifndef newSVpvn
1002
 
    if (size == 0)
1003
 
        data = "" ;
1004
 
#endif
1005
 
 
1006
 
    ENTER ;
1007
 
    SAVETMPS;
1008
 
 
1009
 
    PUSHMARK(SP) ;
1010
 
 
1011
 
    XPUSHs(sv_2mortal(newSVpvn((char*)data,size)));
1012
 
    PUTBACK ;
1013
 
 
1014
 
    count = perl_call_sv(CurrentDB->hash, G_SCALAR);
1015
 
 
1016
 
    SPAGAIN ;
1017
 
 
1018
 
    if (count != 1)
1019
 
        softCrash ("hash_cb: expected 1 return value from hash sub, got %d", count) ;
1020
 
 
1021
 
    retval = POPi ;
1022
 
 
1023
 
    PUTBACK ;
1024
 
    FREETMPS ;
1025
 
    LEAVE ;
1026
 
    CurrentDB = keepDB ;
1027
 
 
1028
 
    return (retval) ;
1029
 
}
1030
 
 
1031
 
#ifdef AT_LEAST_DB_3_3
1032
 
 
1033
 
static int
1034
 
associate_cb(DB_callback const DBT * pkey, const DBT * pdata, DBT * skey)
1035
 
{
1036
 
    dSP ;
1037
 
    char * pk_dat, * pd_dat, *sk_dat ;
1038
 
    int retval ;
1039
 
    int count ;
1040
 
    SV * skey_SV ;
1041
 
 
1042
 
    Trace(("In associate_cb \n")) ;
1043
 
    if (((BerkeleyDB)db->BackRef)->associated == NULL){
1044
 
        Trace(("No Callback registered\n")) ;
1045
 
        return EINVAL ;
1046
 
    }
1047
 
 
1048
 
    skey_SV = newSVpv("",0);
1049
 
 
1050
 
 
1051
 
    pk_dat = (char*) pkey->data ;
1052
 
    pd_dat = (char*) pdata->data ;
1053
 
 
1054
 
#ifndef newSVpvn
1055
 
    /* As newSVpv will assume that the data pointer is a null terminated C
1056
 
       string if the size parameter is 0, make sure that data points to an
1057
 
       empty string if the length is 0
1058
 
    */
1059
 
    if (pkey->size == 0)
1060
 
        pk_dat = "" ;
1061
 
    if (pdata->size == 0)
1062
 
        pd_dat = "" ;
1063
 
#endif
1064
 
 
1065
 
    ENTER ;
1066
 
    SAVETMPS;
1067
 
 
1068
 
    PUSHMARK(SP) ;
1069
 
    EXTEND(SP,2) ;
1070
 
    PUSHs(sv_2mortal(newSVpvn(pk_dat,pkey->size)));
1071
 
    PUSHs(sv_2mortal(newSVpvn(pd_dat,pdata->size)));
1072
 
    PUSHs(sv_2mortal(skey_SV));
1073
 
    PUTBACK ;
1074
 
 
1075
 
    Trace(("calling associated cb\n"));
1076
 
    count = perl_call_sv(((BerkeleyDB)db->BackRef)->associated, G_SCALAR);
1077
 
    Trace(("called associated cb\n"));
1078
 
 
1079
 
    SPAGAIN ;
1080
 
 
1081
 
    if (count != 1)
1082
 
        softCrash ("associate: expected 1 return value from prefix sub, got %d", count) ;
1083
 
 
1084
 
    retval = POPi ;
1085
 
 
1086
 
    PUTBACK ;
1087
 
    
1088
 
    /* retrieve the secondary key */
1089
 
    DBT_clear(*skey);
1090
 
    skey->flags = DB_DBT_APPMALLOC;
1091
 
    skey->size = SvCUR(skey_SV);
1092
 
    skey->data = (char*)safemalloc(skey->size);
1093
 
    memcpy(skey->data, SvPVX(skey_SV), skey->size);
1094
 
    Trace(("key is %d -- %.*s\n", skey->size, skey->size, skey->data));
1095
 
 
1096
 
    FREETMPS ;
1097
 
    LEAVE ;
1098
 
 
1099
 
    return (retval) ;
1100
 
}
1101
 
 
1102
 
#endif /* AT_LEAST_DB_3_3 */
1103
 
 
1104
 
static void
1105
 
db_errcall_cb(const char * db_errpfx, char * buffer)
1106
 
{
1107
 
#if 0
1108
 
 
1109
 
    if (db_errpfx == NULL)
1110
 
        db_errpfx = "" ;
1111
 
    if (buffer == NULL )
1112
 
        buffer = "" ;
1113
 
    ErrBuff[0] = '\0';
1114
 
    if (strlen(db_errpfx) + strlen(buffer) + 3 <= 1000) {
1115
 
        if (*db_errpfx != '\0') {
1116
 
            strcat(ErrBuff, db_errpfx) ;
1117
 
            strcat(ErrBuff, ": ") ;
1118
 
        }
1119
 
        strcat(ErrBuff, buffer) ;
1120
 
    }
1121
 
 
1122
 
#endif
1123
 
 
1124
 
    SV * sv = perl_get_sv(ERR_BUFF, FALSE) ;
1125
 
    if (sv) {
1126
 
        if (db_errpfx)
1127
 
            sv_setpvf(sv, "%s: %s", db_errpfx, buffer) ;
1128
 
        else
1129
 
            sv_setpv(sv, buffer) ;
1130
 
    }
1131
 
}
1132
 
 
1133
 
static SV *
1134
 
readHash(HV * hash, char * key)
1135
 
{
1136
 
    SV **       svp;
1137
 
    svp = hv_fetch(hash, key, strlen(key), FALSE);
1138
 
    if (svp && SvOK(*svp))
1139
 
        return *svp ;
1140
 
    return NULL ;
1141
 
}
1142
 
 
1143
 
static void
1144
 
hash_delete(char * hash, char * key)
1145
 
{
1146
 
    HV * hv = perl_get_hv(hash, TRUE);
1147
 
    (void) hv_delete(hv, (char*)&key, sizeof(key), G_DISCARD);
1148
 
}
1149
 
 
1150
 
static void
1151
 
hash_store_iv(char * hash, char * key, IV value)
1152
 
{
1153
 
    HV * hv = perl_get_hv(hash, TRUE);
1154
 
    (void)hv_store(hv, (char*)&key, sizeof(key), newSViv(value), 0);
1155
 
    /* printf("hv_store returned %d\n", ret) ; */
1156
 
}
1157
 
 
1158
 
static void
1159
 
hv_store_iv(HV * hash, char * key, IV value)
1160
 
{
1161
 
    hv_store(hash, key, strlen(key), newSViv(value), 0);
1162
 
}
1163
 
 
1164
 
static BerkeleyDB
1165
 
my_db_open(
1166
 
                BerkeleyDB      db ,
1167
 
                SV *            ref,
1168
 
                SV *            ref_dbenv ,
1169
 
                BerkeleyDB__Env dbenv ,
1170
 
                BerkeleyDB__Txn txn, 
1171
 
                const char *    file,
1172
 
                const char *    subname,
1173
 
                DBTYPE          type,
1174
 
                int             flags,
1175
 
                int             mode,
1176
 
                DB_INFO *       info
1177
 
        )
1178
 
{
1179
 
    DB_ENV *    env    = NULL ;
1180
 
    BerkeleyDB  RETVAL = NULL ;
1181
 
    DB *        dbp ;
1182
 
    int         Status ;
1183
 
    DB_TXN*     txnid = NULL ;
1184
 
 
1185
 
    Trace(("_db_open(dbenv[%p] ref_dbenv [%p] file[%s] subname [%s] type[%d] flags[%d] mode[%d]\n",
1186
 
                dbenv, ref_dbenv, file, subname, type, flags, mode)) ;
1187
 
 
1188
 
    CurrentDB = db ;
1189
 
    if (dbenv)
1190
 
        env = dbenv->Env ;
1191
 
 
1192
 
    if (txn)
1193
 
        txnid = txn->txn;
1194
 
 
1195
 
    Trace(("_db_open(dbenv[%p] ref_dbenv [%p] txn [%p] file[%s] subname [%s] type[%d] flags[%d] mode[%d]\n",
1196
 
                dbenv, ref_dbenv, txn, file, subname, type, flags, mode)) ;
1197
 
 
1198
 
#if DB_VERSION_MAJOR == 2
1199
 
    if (subname)
1200
 
        softCrash("Subname needs Berkeley DB 3 or better") ;
1201
 
#endif
1202
 
 
1203
 
#if DB_VERSION_MAJOR > 2
1204
 
    Status = db_create(&dbp, env, 0) ;
1205
 
    Trace(("db_create returned %s\n", my_db_strerror(Status))) ;
1206
 
    if (Status)
1207
 
        return RETVAL ;
1208
 
 
1209
 
#ifdef AT_LEAST_DB_3_3
1210
 
    if (! env) {
1211
 
        dbp->set_alloc(dbp, safemalloc, MyRealloc, safefree) ;
1212
 
        dbp->set_errcall(dbp, db_errcall_cb) ;
1213
 
    }
1214
 
#endif
1215
 
 
1216
 
    if (info->re_source) {
1217
 
        Status = dbp->set_re_source(dbp, info->re_source) ;
1218
 
        Trace(("set_re_source [%s] returned %s\n",
1219
 
                info->re_source, my_db_strerror(Status)));
1220
 
        if (Status)
1221
 
            return RETVAL ;
1222
 
    }
1223
 
 
1224
 
    if (info->db_cachesize) {
1225
 
        Status = dbp->set_cachesize(dbp, 0, info->db_cachesize, 0) ;
1226
 
        Trace(("set_cachesize [%d] returned %s\n",
1227
 
                info->db_cachesize, my_db_strerror(Status)));
1228
 
        if (Status)
1229
 
            return RETVAL ;
1230
 
    }
1231
 
 
1232
 
    if (info->db_lorder) {
1233
 
        Status = dbp->set_lorder(dbp, info->db_lorder) ;
1234
 
        Trace(("set_lorder [%d] returned %s\n",
1235
 
                info->db_lorder, my_db_strerror(Status)));
1236
 
        if (Status)
1237
 
            return RETVAL ;
1238
 
    }
1239
 
 
1240
 
    if (info->db_pagesize) {
1241
 
        Status = dbp->set_pagesize(dbp, info->db_pagesize) ;
1242
 
        Trace(("set_pagesize [%d] returned %s\n",
1243
 
                info->db_pagesize, my_db_strerror(Status)));
1244
 
        if (Status)
1245
 
            return RETVAL ;
1246
 
    }
1247
 
 
1248
 
    if (info->h_ffactor) {
1249
 
        Status = dbp->set_h_ffactor(dbp, info->h_ffactor) ;
1250
 
        Trace(("set_h_ffactor [%d] returned %s\n",
1251
 
                info->h_ffactor, my_db_strerror(Status)));
1252
 
        if (Status)
1253
 
            return RETVAL ;
1254
 
    }
1255
 
 
1256
 
    if (info->h_nelem) {
1257
 
        Status = dbp->set_h_nelem(dbp, info->h_nelem) ;
1258
 
        Trace(("set_h_nelem [%d] returned %s\n",
1259
 
                info->h_nelem, my_db_strerror(Status)));
1260
 
        if (Status)
1261
 
            return RETVAL ;
1262
 
    }
1263
 
 
1264
 
    if (info->bt_minkey) {
1265
 
        Status = dbp->set_bt_minkey(dbp, info->bt_minkey) ;
1266
 
        Trace(("set_bt_minkey [%d] returned %s\n",
1267
 
                info->bt_minkey, my_db_strerror(Status)));
1268
 
        if (Status)
1269
 
            return RETVAL ;
1270
 
    }
1271
 
 
1272
 
    if (info->bt_compare) {
1273
 
        Status = dbp->set_bt_compare(dbp, info->bt_compare) ;
1274
 
        Trace(("set_bt_compare [%p] returned %s\n",
1275
 
                info->bt_compare, my_db_strerror(Status)));
1276
 
        if (Status)
1277
 
            return RETVAL ;
1278
 
    }
1279
 
 
1280
 
    if (info->h_hash) {
1281
 
        Status = dbp->set_h_hash(dbp, info->h_hash) ;
1282
 
        Trace(("set_h_hash [%d] returned %s\n",
1283
 
                info->h_hash, my_db_strerror(Status)));
1284
 
        if (Status)
1285
 
            return RETVAL ;
1286
 
    }
1287
 
 
1288
 
    if (info->dup_compare) {
1289
 
        Status = dbp->set_dup_compare(dbp, info->dup_compare) ;
1290
 
        Trace(("set_dup_compare [%d] returned %s\n",
1291
 
                info->dup_compare, my_db_strerror(Status)));
1292
 
        if (Status)
1293
 
            return RETVAL ;
1294
 
    }
1295
 
 
1296
 
    if (info->bt_prefix) {
1297
 
        Status = dbp->set_bt_prefix(dbp, info->bt_prefix) ;
1298
 
        Trace(("set_bt_prefix [%d] returned %s\n",
1299
 
                info->bt_prefix, my_db_strerror(Status)));
1300
 
        if (Status)
1301
 
            return RETVAL ;
1302
 
    }
1303
 
 
1304
 
    if (info->re_len) {
1305
 
        Status = dbp->set_re_len(dbp, info->re_len) ;
1306
 
        Trace(("set_re_len [%d] returned %s\n",
1307
 
                info->re_len, my_db_strerror(Status)));
1308
 
        if (Status)
1309
 
            return RETVAL ;
1310
 
    }
1311
 
 
1312
 
    if (info->re_delim) {
1313
 
        Status = dbp->set_re_delim(dbp, info->re_delim) ;
1314
 
        Trace(("set_re_delim [%d] returned %s\n",
1315
 
                info->re_delim, my_db_strerror(Status)));
1316
 
        if (Status)
1317
 
            return RETVAL ;
1318
 
    }
1319
 
 
1320
 
    if (info->re_pad) {
1321
 
        Status = dbp->set_re_pad(dbp, info->re_pad) ;
1322
 
        Trace(("set_re_pad [%d] returned %s\n",
1323
 
                info->re_pad, my_db_strerror(Status)));
1324
 
        if (Status)
1325
 
            return RETVAL ;
1326
 
    }
1327
 
 
1328
 
    if (info->flags) {
1329
 
        Status = dbp->set_flags(dbp, info->flags) ;
1330
 
        Trace(("set_flags [%d] returned %s\n",
1331
 
                info->flags, my_db_strerror(Status)));
1332
 
        if (Status)
1333
 
            return RETVAL ;
1334
 
    }
1335
 
 
1336
 
    if (info->q_extentsize) {
1337
 
#ifdef AT_LEAST_DB_3_2
1338
 
        Status = dbp->set_q_extentsize(dbp, info->q_extentsize) ;
1339
 
        Trace(("set_flags [%d] returned %s\n",
1340
 
                info->flags, my_db_strerror(Status)));
1341
 
        if (Status)
1342
 
            return RETVAL ;
1343
 
#else
1344
 
        softCrash("-ExtentSize needs at least Berkeley DB 3.2.x") ;
1345
 
#endif
1346
 
    }
1347
 
 
1348
 
#ifdef AT_LEAST_DB_4_1
1349
 
    if ((Status = (dbp->open)(dbp, txnid, file, subname, type, flags, mode)) == 0) {
1350
 
#else
1351
 
    if ((Status = (dbp->open)(dbp, file, subname, type, flags, mode)) == 0) {
1352
 
#endif /* AT_LEAST_DB_4_1 */
1353
 
#else /* DB_VERSION_MAJOR == 2 */
1354
 
    if ((Status = db_open(file, type, flags, mode, env, info, &dbp)) == 0) {
1355
 
#endif /* DB_VERSION_MAJOR == 2 */
1356
 
 
1357
 
        Trace(("db_opened ok\n"));
1358
 
#ifdef AT_LEAST_DB_3_3
1359
 
        dbp->BackRef = db;
1360
 
#endif
1361
 
        RETVAL = db ;
1362
 
        RETVAL->dbp  = dbp ;
1363
 
        RETVAL->txn  = txnid ;
1364
 
#if DB_VERSION_MAJOR == 2
1365
 
        RETVAL->type = dbp->type ;
1366
 
#else /* DB_VERSION_MAJOR > 2 */
1367
 
#ifdef AT_LEAST_DB_3_3
1368
 
        dbp->get_type(dbp, &RETVAL->type) ;
1369
 
#else /* DB 3.0 -> 3.2 */
1370
 
        RETVAL->type = dbp->get_type(dbp) ;
1371
 
#endif
1372
 
#endif /* DB_VERSION_MAJOR > 2 */
1373
 
        RETVAL->recno_or_queue = (RETVAL->type == DB_RECNO ||
1374
 
                                  RETVAL->type == DB_QUEUE) ;
1375
 
        RETVAL->filename = my_strdup(file) ;
1376
 
        RETVAL->Status = Status ;
1377
 
        RETVAL->active = TRUE ;
1378
 
        hash_store_iv("BerkeleyDB::Term::Db", (char *)RETVAL, 1) ;
1379
 
        Trace(("  storing %p %p in BerkeleyDB::Term::Db\n", RETVAL, dbp)) ;
1380
 
        if (dbenv) {
1381
 
            RETVAL->parent_env = dbenv ;
1382
 
            dbenv->Status = Status ;
1383
 
            ++ dbenv->open_dbs ;
1384
 
        }
1385
 
    }
1386
 
    else {
1387
 
#if DB_VERSION_MAJOR > 2
1388
 
        (dbp->close)(dbp, 0) ;
1389
 
#endif
1390
 
        destroyDB(db) ;
1391
 
        Trace(("db open returned %s\n", my_db_strerror(Status))) ;
1392
 
    }
1393
 
 
1394
 
    return RETVAL ;
1395
 
}
1396
 
 
1397
 
 
1398
 
#include "constants.h"
1399
 
 
1400
 
MODULE = BerkeleyDB             PACKAGE = BerkeleyDB    PREFIX = env_
1401
 
 
1402
 
INCLUDE: constants.xs
1403
 
 
1404
 
#define env_db_version(maj, min, patch)         db_version(&maj, &min, &patch)
1405
 
char *
1406
 
env_db_version(maj, min, patch)
1407
 
        int  maj
1408
 
        int  min
1409
 
        int  patch
1410
 
        OUTPUT:
1411
 
          RETVAL
1412
 
          maj
1413
 
          min
1414
 
          patch
1415
 
 
1416
 
int
1417
 
db_value_set(value, which)
1418
 
        int value
1419
 
        int which
1420
 
        NOT_IMPLEMENTED_YET
1421
 
 
1422
 
 
1423
 
DualType
1424
 
_db_remove(ref)
1425
 
        SV *            ref
1426
 
        CODE:
1427
 
        {
1428
 
#if DB_VERSION_MAJOR == 2
1429
 
            softCrash("BerkeleyDB::db_remove needs Berkeley DB 3.x or better") ;
1430
 
#else
1431
 
            HV *                hash ;
1432
 
            DB *                dbp ;
1433
 
            SV *                sv ;
1434
 
            const char *        db = NULL ;
1435
 
            const char *        subdb   = NULL ;
1436
 
            BerkeleyDB__Env     env     = NULL ;
1437
 
            DB_ENV *            dbenv   = NULL ;
1438
 
            u_int32_t           flags   = 0 ;
1439
 
 
1440
 
            hash = (HV*) SvRV(ref) ;
1441
 
            SetValue_pv(db,    "Filename", char *) ;
1442
 
            SetValue_pv(subdb, "Subname", char *) ;
1443
 
            SetValue_iv(flags, "Flags") ;
1444
 
            SetValue_ov(env, "Env", BerkeleyDB__Env) ;
1445
 
            if (env)
1446
 
                dbenv = env->Env ;
1447
 
            RETVAL = db_create(&dbp, dbenv, 0) ;
1448
 
            if (RETVAL == 0) {
1449
 
                RETVAL = dbp->remove(dbp, db, subdb, flags) ;
1450
 
            }
1451
 
#endif
1452
 
        }
1453
 
        OUTPUT:
1454
 
            RETVAL
1455
 
 
1456
 
DualType
1457
 
_db_verify(ref)
1458
 
        SV *            ref
1459
 
        CODE:
1460
 
        {
1461
 
#ifndef AT_LEAST_DB_3_1
1462
 
            softCrash("BerkeleyDB::db_verify needs Berkeley DB 3.1.x or better") ;
1463
 
#else
1464
 
            HV *                hash ;
1465
 
            DB *                dbp ;
1466
 
            SV *                sv ;
1467
 
            const char *        db = NULL ;
1468
 
            const char *        subdb   = NULL ;
1469
 
            const char *        outfile = NULL ;
1470
 
            FILE *              ofh = NULL;
1471
 
            BerkeleyDB__Env     env     = NULL ;
1472
 
            DB_ENV *            dbenv   = NULL ;
1473
 
            u_int32_t           flags   = 0 ;
1474
 
 
1475
 
            hash = (HV*) SvRV(ref) ;
1476
 
            SetValue_pv(db,    "Filename", char *) ;
1477
 
            SetValue_pv(subdb, "Subname", char *) ;
1478
 
            SetValue_pv(outfile, "Outfile", char *) ;
1479
 
            SetValue_iv(flags, "Flags") ;
1480
 
            SetValue_ov(env, "Env", BerkeleyDB__Env) ;
1481
 
            RETVAL = 0;
1482
 
            if (outfile){
1483
 
                ofh = fopen(outfile, "w");
1484
 
                if (! ofh)
1485
 
                    RETVAL = errno;
1486
 
            }
1487
 
            if (! RETVAL) {
1488
 
                if (env)
1489
 
                    dbenv = env->Env ;
1490
 
                RETVAL = db_create(&dbp, dbenv, 0) ;
1491
 
                if (RETVAL == 0) {
1492
 
                    RETVAL = dbp->verify(dbp, db, subdb, ofh, flags) ;
1493
 
                }
1494
 
                if (outfile) 
1495
 
                    fclose(ofh);
1496
 
            }
1497
 
#endif
1498
 
        }
1499
 
        OUTPUT:
1500
 
            RETVAL
1501
 
 
1502
 
DualType
1503
 
_db_rename(ref)
1504
 
        SV *            ref
1505
 
        CODE:
1506
 
        {
1507
 
#ifndef AT_LEAST_DB_3_1
1508
 
            softCrash("BerkeleyDB::db_rename needs Berkeley DB 3.1.x or better") ;
1509
 
#else
1510
 
            HV *                hash ;
1511
 
            DB *                dbp ;
1512
 
            SV *                sv ;
1513
 
            const char *        db = NULL ;
1514
 
            const char *        subdb   = NULL ;
1515
 
            const char *        newname = NULL ;
1516
 
            BerkeleyDB__Env     env     = NULL ;
1517
 
            DB_ENV *            dbenv   = NULL ;
1518
 
            u_int32_t           flags   = 0 ;
1519
 
 
1520
 
            hash = (HV*) SvRV(ref) ;
1521
 
            SetValue_pv(db,    "Filename", char *) ;
1522
 
            SetValue_pv(subdb, "Subname", char *) ;
1523
 
            SetValue_pv(newname, "Newname", char *) ;
1524
 
            SetValue_iv(flags, "Flags") ;
1525
 
            SetValue_ov(env, "Env", BerkeleyDB__Env) ;
1526
 
            if (env)
1527
 
                dbenv = env->Env ;
1528
 
            RETVAL = db_create(&dbp, dbenv, 0) ;
1529
 
            if (RETVAL == 0) {
1530
 
                RETVAL = dbp->rename(dbp, db, subdb, newname, flags) ;
1531
 
            }
1532
 
#endif
1533
 
        }
1534
 
        OUTPUT:
1535
 
            RETVAL
1536
 
 
1537
 
MODULE = BerkeleyDB::Env                PACKAGE = BerkeleyDB::Env PREFIX = env_
1538
 
 
1539
 
 
1540
 
BerkeleyDB::Env::Raw
1541
 
_db_appinit(self, ref)
1542
 
        char *          self
1543
 
        SV *            ref
1544
 
        CODE:
1545
 
        {
1546
 
            HV *        hash ;
1547
 
            SV *        sv ;
1548
 
            char *      home = NULL ;
1549
 
            char *      errfile = NULL ;
1550
 
            char *      server = NULL ;
1551
 
            char **     config = NULL ;
1552
 
            int         flags = 0 ;
1553
 
            int         setflags = 0 ;
1554
 
            int         cachesize = 0 ;
1555
 
            int         lk_detect = 0 ;
1556
 
            SV *        errprefix = NULL;
1557
 
            DB_ENV *    env ;
1558
 
            int status ;
1559
 
 
1560
 
            Trace(("in _db_appinit [%s] %d\n", self, ref)) ;
1561
 
            hash = (HV*) SvRV(ref) ;
1562
 
            SetValue_pv(home,      "Home", char *) ;
1563
 
            SetValue_pv(config,    "Config", char **) ;
1564
 
            SetValue_sv(errprefix, "ErrPrefix") ;
1565
 
            SetValue_iv(flags,     "Flags") ;
1566
 
            SetValue_iv(setflags,  "SetFlags") ;
1567
 
            SetValue_pv(server,    "Server", char *) ;
1568
 
            SetValue_iv(cachesize, "Cachesize") ;
1569
 
            SetValue_iv(lk_detect, "LockDetect") ;
1570
 
#ifndef AT_LEAST_DB_3_2
1571
 
            if (setflags)
1572
 
                softCrash("-SetFlags needs Berkeley DB 3.x or better") ;
1573
 
#endif /* ! AT_LEAST_DB_3 */
1574
 
#ifndef AT_LEAST_DB_3_1
1575
 
            if (server)
1576
 
                softCrash("-Server needs Berkeley DB 3.1 or better") ;
1577
 
#endif /* ! AT_LEAST_DB_3_1 */
1578
 
            Trace(("_db_appinit(config=[%d], home=[%s],errprefix=[%s],flags=[%d]\n",
1579
 
                        config, home, errprefix, flags)) ;
1580
 
#ifdef TRACE
1581
 
            if (config) {
1582
 
               int i ;
1583
 
              for (i = 0 ; i < 10 ; ++ i) {
1584
 
                if (config[i] == NULL) {
1585
 
                    printf("    End\n") ;
1586
 
                    break ;
1587
 
                }
1588
 
                printf("    config = [%s]\n", config[i]) ;
1589
 
              }
1590
 
            }
1591
 
#endif /* TRACE */
1592
 
            ZMALLOC(RETVAL, BerkeleyDB_ENV_type) ;
1593
 
            if (flags & DB_INIT_TXN)
1594
 
                RETVAL->txn_enabled = TRUE ;
1595
 
#if DB_VERSION_MAJOR == 2
1596
 
          ZMALLOC(RETVAL->Env, DB_ENV) ;
1597
 
          env = RETVAL->Env ;
1598
 
          {
1599
 
            /* Take a copy of the error prefix */
1600
 
            if (errprefix) {
1601
 
                Trace(("copying errprefix\n" )) ;
1602
 
                RETVAL->ErrPrefix = newSVsv(errprefix) ;
1603
 
                SvPOK_only(RETVAL->ErrPrefix) ;
1604
 
            }
1605
 
            if (RETVAL->ErrPrefix)
1606
 
                RETVAL->Env->db_errpfx = SvPVX(RETVAL->ErrPrefix) ;
1607
 
 
1608
 
            SetValue_pv(errfile,      "ErrFile", char *) ;
1609
 
            if (errfile) {
1610
 
                RETVAL->ErrHandle = env->db_errfile = fopen(errfile, "w");
1611
 
                if (RETVAL->ErrHandle == NULL)
1612
 
                    croak("Cannot open file %s: %s\n", errfile,  Strerror(errno));
1613
 
            }
1614
 
            SetValue_iv(env->db_verbose, "Verbose") ;
1615
 
            env->db_errcall = db_errcall_cb ;
1616
 
            RETVAL->active = TRUE ;
1617
 
            status = db_appinit(home, config, env, flags) ;
1618
 
            Trace(("  status = %d env %d Env %d\n", status, RETVAL, env)) ;
1619
 
            if (status == 0)
1620
 
                hash_store_iv("BerkeleyDB::Term::Env", (char *)RETVAL, 1) ;
1621
 
            else {
1622
 
                if (RETVAL->ErrHandle)
1623
 
                    fclose(RETVAL->ErrHandle) ;
1624
 
                if (RETVAL->ErrPrefix)
1625
 
                    SvREFCNT_dec(RETVAL->ErrPrefix) ;
1626
 
                Safefree(RETVAL->Env) ;
1627
 
                Safefree(RETVAL) ;
1628
 
                RETVAL = NULL ;
1629
 
            }
1630
 
          }
1631
 
#else /* DB_VERSION_MAJOR > 2 */
1632
 
#ifndef AT_LEAST_DB_3_1
1633
 
#    define DB_CLIENT   0
1634
 
#endif
1635
 
          status = db_env_create(&RETVAL->Env, server ? DB_CLIENT : 0) ;
1636
 
          Trace(("db_env_create flags = %d returned %s\n", flags,
1637
 
                                                my_db_strerror(status))) ;
1638
 
          env = RETVAL->Env ;
1639
 
#ifdef AT_LEAST_DB_3_3
1640
 
          env->set_alloc(env, safemalloc, MyRealloc, safefree) ;
1641
 
#endif
1642
 
          if (status == 0 && cachesize) {
1643
 
              status = env->set_cachesize(env, 0, cachesize, 0) ;
1644
 
              Trace(("set_cachesize [%d] returned %s\n",
1645
 
                        cachesize, my_db_strerror(status)));
1646
 
          }
1647
 
        
1648
 
          if (status == 0 && lk_detect) {
1649
 
              status = env->set_lk_detect(env, lk_detect) ;
1650
 
              Trace(("set_lk_detect [%d] returned %s\n",
1651
 
                      lk_detect, my_db_strerror(status)));
1652
 
          }
1653
 
#ifdef AT_LEAST_DB_4
1654
 
          /* set the server */
1655
 
          if (server && status == 0)
1656
 
          {
1657
 
              status = env->set_rpc_server(env, NULL, server, 0, 0, 0);
1658
 
              Trace(("ENV->set_rpc_server server = %s returned %s\n", server,
1659
 
                                                my_db_strerror(status))) ;
1660
 
          }
1661
 
#else
1662
 
#  if defined(AT_LEAST_DB_3_1) && ! defined(AT_LEAST_DB_4)
1663
 
          /* set the server */
1664
 
          if (server && status == 0)
1665
 
          {
1666
 
              status = env->set_server(env, server, 0, 0, 0);
1667
 
              Trace(("ENV->set_server server = %s returned %s\n", server,
1668
 
                                                my_db_strerror(status))) ;
1669
 
          }
1670
 
#  endif
1671
 
#endif
1672
 
#ifdef AT_LEAST_DB_3_2
1673
 
          if (setflags && status == 0)
1674
 
          {
1675
 
              status = env->set_flags(env, setflags, 1);
1676
 
              Trace(("ENV->set_flags value = %d returned %s\n", setflags,
1677
 
                                                my_db_strerror(status))) ;
1678
 
          }
1679
 
#endif
1680
 
          if (status == 0)
1681
 
          {
1682
 
            int         mode = 0 ;
1683
 
            /* Take a copy of the error prefix */
1684
 
            if (errprefix) {
1685
 
                Trace(("copying errprefix\n" )) ;
1686
 
                RETVAL->ErrPrefix = newSVsv(errprefix) ;
1687
 
                SvPOK_only(RETVAL->ErrPrefix) ;
1688
 
            }
1689
 
            if (RETVAL->ErrPrefix)
1690
 
                env->set_errpfx(env, SvPVX(RETVAL->ErrPrefix)) ;
1691
 
 
1692
 
            SetValue_pv(errfile,      "ErrFile", char *) ;
1693
 
            if (errfile) {
1694
 
                RETVAL->ErrHandle = fopen(errfile, "w");
1695
 
                if (RETVAL->ErrHandle == NULL)
1696
 
                    croak("Cannot open file %s: %s\n", errfile,  Strerror(errno));
1697
 
                env->set_errfile(env, RETVAL->ErrHandle) ;
1698
 
            }
1699
 
 
1700
 
            SetValue_iv(mode, "Mode") ;
1701
 
            env->set_errcall(env, db_errcall_cb) ;
1702
 
            RETVAL->active = TRUE ;
1703
 
#ifdef IS_DB_3_0_x
1704
 
            status = (env->open)(env, home, config, flags, mode) ;
1705
 
#else /* > 3.0 */
1706
 
            status = (env->open)(env, home, flags, mode) ;
1707
 
#endif
1708
 
            Trace(("ENV->open returned %s\n", my_db_strerror(status))) ;
1709
 
          }
1710
 
 
1711
 
          if (status == 0)
1712
 
              hash_store_iv("BerkeleyDB::Term::Env", (char *)RETVAL, 1) ;
1713
 
          else {
1714
 
              (env->close)(env, 0) ;
1715
 
              if (RETVAL->ErrHandle)
1716
 
                  fclose(RETVAL->ErrHandle) ;
1717
 
              if (RETVAL->ErrPrefix)
1718
 
                  SvREFCNT_dec(RETVAL->ErrPrefix) ;
1719
 
              Safefree(RETVAL) ;
1720
 
              RETVAL = NULL ;
1721
 
          }
1722
 
#endif /* DB_VERSION_MAJOR > 2 */
1723
 
        }
1724
 
        OUTPUT:
1725
 
            RETVAL
1726
 
 
1727
 
void
1728
 
log_archive(env, flags=0)
1729
 
        u_int32_t               flags
1730
 
        BerkeleyDB::Env         env
1731
 
        PPCODE:
1732
 
        {
1733
 
          char ** list;
1734
 
          char ** file;
1735
 
          AV    * av;
1736
 
#ifndef AT_LEAST_DB_3
1737
 
          softCrash("log_archive needs at least Berkeley DB 3.x.x");
1738
 
#else
1739
 
#  ifdef AT_LEAST_DB_4
1740
 
          env->Status = env->Env->log_archive(env->Env, &list, flags) ;
1741
 
#  else
1742
 
#    ifdef AT_LEAST_DB_3_3
1743
 
          env->Status = log_archive(env->Env, &list, flags) ;
1744
 
#    else
1745
 
          env->Status = log_archive(env->Env, &list, flags, safemalloc) ;
1746
 
#    endif
1747
 
#  endif
1748
 
          if (env->Status == 0 && list != NULL)
1749
 
          {
1750
 
              for (file = list; *file != NULL; ++file)
1751
 
              {
1752
 
                XPUSHs(sv_2mortal(newSVpv(*file, 0))) ;
1753
 
              }
1754
 
              safefree(list);
1755
 
          }
1756
 
#endif
1757
 
        }
1758
 
 
1759
 
BerkeleyDB::Txn::Raw
1760
 
_txn_begin(env, pid=NULL, flags=0)
1761
 
        u_int32_t               flags
1762
 
        BerkeleyDB::Env         env
1763
 
        BerkeleyDB::Txn         pid
1764
 
        CODE:
1765
 
        {
1766
 
            DB_TXN *txn ;
1767
 
            DB_TXN *p_id = NULL ;
1768
 
            Trace(("txn_begin pid %d, flags %d\n", pid, flags)) ;
1769
 
#if DB_VERSION_MAJOR == 2
1770
 
            if (env->Env->tx_info == NULL)
1771
 
                softCrash("Transaction Manager not enabled") ;
1772
 
#endif
1773
 
            if (!env->txn_enabled)
1774
 
                softCrash("Transaction Manager not enabled") ;
1775
 
            if (pid)
1776
 
                p_id = pid->txn ;
1777
 
            env->TxnMgrStatus =
1778
 
#if DB_VERSION_MAJOR == 2
1779
 
                txn_begin(env->Env->tx_info, p_id, &txn) ;
1780
 
#else
1781
 
#  ifdef AT_LEAST_DB_4
1782
 
                env->Env->txn_begin(env->Env, p_id, &txn, flags) ;
1783
 
#  else
1784
 
                txn_begin(env->Env, p_id, &txn, flags) ;
1785
 
#  endif
1786
 
#endif
1787
 
            if (env->TxnMgrStatus == 0) {
1788
 
              ZMALLOC(RETVAL, BerkeleyDB_Txn_type) ;
1789
 
              RETVAL->txn  = txn ;
1790
 
              RETVAL->active = TRUE ;
1791
 
              Trace(("_txn_begin created txn [%p] in [%p]\n", txn, RETVAL));
1792
 
              hash_store_iv("BerkeleyDB::Term::Txn", (char *)RETVAL, 1) ;
1793
 
            }
1794
 
            else
1795
 
                RETVAL = NULL ;
1796
 
        }
1797
 
        OUTPUT:
1798
 
            RETVAL
1799
 
 
1800
 
 
1801
 
#if DB_VERSION_MAJOR == 2
1802
 
#  define env_txn_checkpoint(e,k,m,f) txn_checkpoint(e->Env->tx_info, k, m)
1803
 
#else /* DB 3.0 or better */
1804
 
#  ifdef AT_LEAST_DB_4 
1805
 
#    define env_txn_checkpoint(e,k,m,f) e->Env->txn_checkpoint(e->Env, k, m, f)
1806
 
#  else
1807
 
#    ifdef AT_LEAST_DB_3_1
1808
 
#      define env_txn_checkpoint(e,k,m,f) txn_checkpoint(e->Env, k, m, 0)
1809
 
#    else
1810
 
#      define env_txn_checkpoint(e,k,m,f) txn_checkpoint(e->Env, k, m)
1811
 
#    endif
1812
 
#  endif
1813
 
#endif
1814
 
DualType
1815
 
env_txn_checkpoint(env, kbyte, min, flags=0)
1816
 
        BerkeleyDB::Env         env
1817
 
        long                    kbyte
1818
 
        long                    min
1819
 
        u_int32_t               flags
1820
 
 
1821
 
HV *
1822
 
txn_stat(env)
1823
 
        BerkeleyDB::Env         env
1824
 
        HV *                    RETVAL = NULL ;
1825
 
        CODE:
1826
 
        {
1827
 
            DB_TXN_STAT *       stat ;
1828
 
#ifdef AT_LEAST_DB_4
1829
 
            if(env->Env->txn_stat(env->Env, &stat, 0) == 0) {
1830
 
#else
1831
 
#  ifdef AT_LEAST_DB_3_3
1832
 
            if(txn_stat(env->Env, &stat) == 0) {
1833
 
#  else
1834
 
#    if DB_VERSION_MAJOR == 2
1835
 
            if(txn_stat(env->Env->tx_info, &stat, safemalloc) == 0) {
1836
 
#    else
1837
 
            if(txn_stat(env->Env, &stat, safemalloc) == 0) {
1838
 
#    endif
1839
 
#  endif
1840
 
#endif
1841
 
                RETVAL = (HV*)sv_2mortal((SV*)newHV()) ;
1842
 
                hv_store_iv(RETVAL, "st_time_ckp", stat->st_time_ckp) ;
1843
 
                hv_store_iv(RETVAL, "st_last_txnid", stat->st_last_txnid) ;
1844
 
                hv_store_iv(RETVAL, "st_maxtxns", stat->st_maxtxns) ;
1845
 
                hv_store_iv(RETVAL, "st_naborts", stat->st_naborts) ;
1846
 
                hv_store_iv(RETVAL, "st_nbegins", stat->st_nbegins) ;
1847
 
                hv_store_iv(RETVAL, "st_ncommits", stat->st_ncommits) ;
1848
 
                hv_store_iv(RETVAL, "st_nactive", stat->st_nactive) ;
1849
 
#if DB_VERSION_MAJOR > 2
1850
 
                hv_store_iv(RETVAL, "st_maxnactive", stat->st_maxnactive) ;
1851
 
                hv_store_iv(RETVAL, "st_regsize", stat->st_regsize) ;
1852
 
                hv_store_iv(RETVAL, "st_region_wait", stat->st_region_wait) ;
1853
 
                hv_store_iv(RETVAL, "st_region_nowait", stat->st_region_nowait) ;
1854
 
#endif
1855
 
                safefree(stat) ;
1856
 
            }
1857
 
        }
1858
 
        OUTPUT:
1859
 
            RETVAL
1860
 
 
1861
 
#define EnDis(x)        ((x) ? "Enabled" : "Disabled")
1862
 
void
1863
 
printEnv(env)
1864
 
        BerkeleyDB::Env  env
1865
 
        INIT:
1866
 
            ckActive_Environment(env->active) ;
1867
 
        CODE:
1868
 
#if 0
1869
 
          printf("env             [0x%X]\n", env) ;
1870
 
          printf("  ErrPrefix     [%s]\n", env->ErrPrefix
1871
 
                                           ? SvPVX(env->ErrPrefix) : 0) ;
1872
 
          printf("  DB_ENV\n") ;
1873
 
          printf("    db_lorder   [%d]\n", env->Env.db_lorder) ;
1874
 
          printf("    db_home     [%s]\n", env->Env.db_home) ;
1875
 
          printf("    db_data_dir [%s]\n", env->Env.db_data_dir) ;
1876
 
          printf("    db_log_dir  [%s]\n", env->Env.db_log_dir) ;
1877
 
          printf("    db_tmp_dir  [%s]\n", env->Env.db_tmp_dir) ;
1878
 
          printf("    lk_info     [%s]\n", EnDis(env->Env.lk_info)) ;
1879
 
          printf("    lk_max      [%d]\n", env->Env.lk_max) ;
1880
 
          printf("    lg_info     [%s]\n", EnDis(env->Env.lg_info)) ;
1881
 
          printf("    lg_max      [%d]\n", env->Env.lg_max) ;
1882
 
          printf("    mp_info     [%s]\n", EnDis(env->Env.mp_info)) ;
1883
 
          printf("    mp_size     [%d]\n", env->Env.mp_size) ;
1884
 
          printf("    tx_info     [%s]\n", EnDis(env->Env.tx_info)) ;
1885
 
          printf("    tx_max      [%d]\n", env->Env.tx_max) ;
1886
 
          printf("    flags       [%d]\n", env->Env.flags) ;
1887
 
          printf("\n") ;
1888
 
#endif
1889
 
 
1890
 
SV *
1891
 
errPrefix(env, prefix)
1892
 
        BerkeleyDB::Env  env
1893
 
        SV *             prefix
1894
 
        INIT:
1895
 
            ckActive_Environment(env->active) ;
1896
 
        CODE:
1897
 
          if (env->ErrPrefix) {
1898
 
              RETVAL = newSVsv(env->ErrPrefix) ;
1899
 
              SvPOK_only(RETVAL) ;
1900
 
              sv_setsv(env->ErrPrefix, prefix) ;
1901
 
          }
1902
 
          else {
1903
 
              RETVAL = NULL ;
1904
 
              env->ErrPrefix = newSVsv(prefix) ;
1905
 
          }
1906
 
          SvPOK_only(env->ErrPrefix) ;
1907
 
#if DB_VERSION_MAJOR == 2
1908
 
          env->Env->db_errpfx = SvPVX(env->ErrPrefix) ;
1909
 
#else
1910
 
          env->Env->set_errpfx(env->Env, SvPVX(env->ErrPrefix)) ;
1911
 
#endif
1912
 
        OUTPUT:
1913
 
          RETVAL
1914
 
 
1915
 
DualType
1916
 
status(env)
1917
 
        BerkeleyDB::Env         env
1918
 
        CODE:
1919
 
            RETVAL =  env->Status ;
1920
 
        OUTPUT:
1921
 
            RETVAL
1922
 
 
1923
 
DualType
1924
 
db_appexit(env)
1925
 
        BerkeleyDB::Env         env
1926
 
        ALIAS:  close =1
1927
 
        INIT:
1928
 
            ckActive_Environment(env->active) ;
1929
 
        CODE:
1930
 
#ifdef STRICT_CLOSE
1931
 
            if (env->open_dbs)
1932
 
                softCrash("attempted to close an environment with %d open database(s)",
1933
 
                        env->open_dbs) ;
1934
 
#endif /* STRICT_CLOSE */
1935
 
#if DB_VERSION_MAJOR == 2
1936
 
            RETVAL = db_appexit(env->Env) ;
1937
 
#else
1938
 
            RETVAL = (env->Env->close)(env->Env, 0) ;
1939
 
#endif
1940
 
            env->active = FALSE ;
1941
 
            hash_delete("BerkeleyDB::Term::Env", (char *)env) ;
1942
 
        OUTPUT:
1943
 
            RETVAL
1944
 
 
1945
 
 
1946
 
void
1947
 
_DESTROY(env)
1948
 
        BerkeleyDB::Env  env
1949
 
        int RETVAL = 0 ;
1950
 
        CODE:
1951
 
          Trace(("In BerkeleyDB::Env::DESTROY\n"));
1952
 
          Trace(("    env %ld Env %ld dirty %d\n", env, &env->Env, PL_dirty)) ;
1953
 
          if (env->active)
1954
 
#if DB_VERSION_MAJOR == 2
1955
 
              db_appexit(env->Env) ;
1956
 
#else
1957
 
              (env->Env->close)(env->Env, 0) ;
1958
 
#endif
1959
 
          if (env->ErrHandle)
1960
 
              fclose(env->ErrHandle) ;
1961
 
          if (env->ErrPrefix)
1962
 
              SvREFCNT_dec(env->ErrPrefix) ;
1963
 
#if DB_VERSION_MAJOR == 2
1964
 
          Safefree(env->Env) ;
1965
 
#endif
1966
 
          Safefree(env) ;
1967
 
          hash_delete("BerkeleyDB::Term::Env", (char *)env) ;
1968
 
          Trace(("End of BerkeleyDB::Env::DESTROY %d\n", RETVAL)) ;
1969
 
 
1970
 
BerkeleyDB::TxnMgr::Raw
1971
 
_TxnMgr(env)
1972
 
        BerkeleyDB::Env  env
1973
 
        INIT:
1974
 
            ckActive_Environment(env->active) ;
1975
 
            if (!env->txn_enabled)
1976
 
                softCrash("Transaction Manager not enabled") ;
1977
 
        CODE:
1978
 
            ZMALLOC(RETVAL, BerkeleyDB_TxnMgr_type) ;
1979
 
            RETVAL->env  = env ;
1980
 
            /* hash_store_iv("BerkeleyDB::Term::TxnMgr", (char *)txn, 1) ; */
1981
 
        OUTPUT:
1982
 
            RETVAL
1983
 
 
1984
 
int
1985
 
set_lg_dir(env, dir)
1986
 
        BerkeleyDB::Env  env
1987
 
        char *           dir
1988
 
        INIT:
1989
 
          ckActive_Database(env->active) ;
1990
 
        CODE:
1991
 
#ifndef AT_LEAST_DB_3_1
1992
 
            softCrash("$env->set_lg_dir needs Berkeley DB 3.1 or better") ;
1993
 
#else
1994
 
            RETVAL = env->Status = env->Env->set_lg_dir(env->Env, dir);
1995
 
#endif
1996
 
        OUTPUT:
1997
 
            RETVAL
1998
 
 
1999
 
int
2000
 
set_lg_bsize(env, bsize)
2001
 
        BerkeleyDB::Env  env
2002
 
        u_int32_t        bsize
2003
 
        INIT:
2004
 
          ckActive_Database(env->active) ;
2005
 
        CODE:
2006
 
#ifndef AT_LEAST_DB_3
2007
 
            softCrash("$env->set_lg_bsize needs Berkeley DB 3.0.55 or better") ;
2008
 
#else
2009
 
            RETVAL = env->Status = env->Env->set_lg_bsize(env->Env, bsize);
2010
 
#endif
2011
 
        OUTPUT:
2012
 
            RETVAL
2013
 
 
2014
 
int
2015
 
set_lg_max(env, lg_max)
2016
 
        BerkeleyDB::Env  env
2017
 
        u_int32_t        lg_max
2018
 
        INIT:
2019
 
          ckActive_Database(env->active) ;
2020
 
        CODE:
2021
 
#ifndef AT_LEAST_DB_3
2022
 
            softCrash("$env->set_lg_max needs Berkeley DB 3.0.55 or better") ;
2023
 
#else
2024
 
            RETVAL = env->Status = env->Env->set_lg_max(env->Env, lg_max);
2025
 
#endif
2026
 
        OUTPUT:
2027
 
            RETVAL
2028
 
 
2029
 
int
2030
 
set_data_dir(env, dir)
2031
 
        BerkeleyDB::Env  env
2032
 
        char *           dir
2033
 
        INIT:
2034
 
          ckActive_Database(env->active) ;
2035
 
        CODE:
2036
 
#ifndef AT_LEAST_DB_3_1
2037
 
            softCrash("$env->set_data_dir needs Berkeley DB 3.1 or better") ;
2038
 
#else
2039
 
            RETVAL = env->Status = env->Env->set_data_dir(env->Env, dir);
2040
 
#endif
2041
 
        OUTPUT:
2042
 
            RETVAL
2043
 
 
2044
 
int
2045
 
set_tmp_dir(env, dir)
2046
 
        BerkeleyDB::Env  env
2047
 
        char *           dir
2048
 
        INIT:
2049
 
          ckActive_Database(env->active) ;
2050
 
        CODE:
2051
 
#ifndef AT_LEAST_DB_3_1
2052
 
            softCrash("$env->set_tmp_dir needs Berkeley DB 3.1 or better") ;
2053
 
#else
2054
 
            RETVAL = env->Status = env->Env->set_tmp_dir(env->Env, dir);
2055
 
#endif
2056
 
        OUTPUT:
2057
 
            RETVAL
2058
 
 
2059
 
int
2060
 
set_mutexlocks(env, do_lock)
2061
 
        BerkeleyDB::Env  env
2062
 
        int              do_lock
2063
 
        INIT:
2064
 
          ckActive_Database(env->active) ;
2065
 
        CODE:
2066
 
#ifndef AT_LEAST_DB_3
2067
 
            softCrash("$env->set_setmutexlocks needs Berkeley DB 3.0 or better") ;
2068
 
#else
2069
 
#  ifdef AT_LEAST_DB_4
2070
 
            RETVAL = env->Status = env->Env->set_flags(env->Env, DB_NOLOCKING, do_lock);
2071
 
#  else
2072
 
#    if defined(AT_LEAST_DB_3_2_6) || defined(IS_DB_3_0_x)
2073
 
            RETVAL = env->Status = env->Env->set_mutexlocks(env->Env, do_lock);
2074
 
#    else /* DB 3.1 or 3.2.3 */
2075
 
            RETVAL = env->Status = db_env_set_mutexlocks(do_lock);
2076
 
#    endif
2077
 
#  endif
2078
 
#endif
2079
 
        OUTPUT:
2080
 
            RETVAL
2081
 
 
2082
 
int
2083
 
set_verbose(env, which, onoff)
2084
 
        BerkeleyDB::Env  env
2085
 
        u_int32_t        which
2086
 
        int              onoff
2087
 
        INIT:
2088
 
          ckActive_Database(env->active) ;
2089
 
        CODE:
2090
 
#ifndef AT_LEAST_DB_3
2091
 
            softCrash("$env->set_verbose needs Berkeley DB 3.x or better") ;
2092
 
#else
2093
 
            RETVAL = env->Status = env->Env->set_verbose(env->Env, which, onoff);
2094
 
#endif
2095
 
        OUTPUT:
2096
 
            RETVAL
2097
 
 
2098
 
int
2099
 
set_flags(env, flags, onoff)
2100
 
        BerkeleyDB::Env  env
2101
 
        u_int32_t        flags
2102
 
        int              onoff
2103
 
        INIT:
2104
 
          ckActive_Database(env->active) ;
2105
 
        CODE:
2106
 
#ifndef AT_LEAST_DB_3_2
2107
 
            softCrash("$env->set_flags needs Berkeley DB 3.2.x or better") ;
2108
 
#else
2109
 
            RETVAL = env->Status = env->Env->set_flags(env->Env, flags, onoff);
2110
 
#endif
2111
 
        OUTPUT:
2112
 
            RETVAL
2113
 
 
2114
 
 
2115
 
MODULE = BerkeleyDB::Term               PACKAGE = BerkeleyDB::Term
2116
 
 
2117
 
void
2118
 
close_everything()
2119
 
 
2120
 
#define safeCroak(string)       softCrash(string)
2121
 
void
2122
 
safeCroak(string)
2123
 
        char * string
2124
 
 
2125
 
MODULE = BerkeleyDB::Hash       PACKAGE = BerkeleyDB::Hash      PREFIX = hash_
2126
 
 
2127
 
BerkeleyDB::Hash::Raw
2128
 
_db_open_hash(self, ref)
2129
 
        char *          self
2130
 
        SV *            ref
2131
 
        CODE:
2132
 
        {
2133
 
            HV *                hash ;
2134
 
            SV *                sv ;
2135
 
            DB_INFO             info ;
2136
 
            BerkeleyDB__Env     dbenv = NULL;
2137
 
            SV *                ref_dbenv = NULL;
2138
 
            const char *        file = NULL ;
2139
 
            const char *        subname = NULL ;
2140
 
            int                 flags = 0 ;
2141
 
            int                 mode = 0 ;
2142
 
            BerkeleyDB          db ;
2143
 
            BerkeleyDB__Txn     txn = NULL ;
2144
 
 
2145
 
            Trace(("_db_open_hash start\n")) ;
2146
 
            hash = (HV*) SvRV(ref) ;
2147
 
            SetValue_pv(file, "Filename", char *) ;
2148
 
            SetValue_pv(subname, "Subname", char *) ;
2149
 
            SetValue_ov(txn, "Txn", BerkeleyDB__Txn) ;
2150
 
            SetValue_ov(dbenv, "Env", BerkeleyDB__Env) ;
2151
 
            ref_dbenv = sv ;
2152
 
            SetValue_iv(flags, "Flags") ;
2153
 
            SetValue_iv(mode, "Mode") ;
2154
 
 
2155
 
            Zero(&info, 1, DB_INFO) ;
2156
 
            SetValue_iv(info.db_cachesize, "Cachesize") ;
2157
 
            SetValue_iv(info.db_lorder, "Lorder") ;
2158
 
            SetValue_iv(info.db_pagesize, "Pagesize") ;
2159
 
            SetValue_iv(info.h_ffactor, "Ffactor") ;
2160
 
            SetValue_iv(info.h_nelem, "Nelem") ;
2161
 
            SetValue_iv(info.flags, "Property") ;
2162
 
            ZMALLOC(db, BerkeleyDB_type) ;
2163
 
            if ((sv = readHash(hash, "Hash")) && sv != &PL_sv_undef) {
2164
 
                info.h_hash = hash_cb ;
2165
 
                db->hash = newSVsv(sv) ;
2166
 
            }
2167
 
            /* DB_DUPSORT was introduced in DB 2.5.9 */
2168
 
            if ((sv = readHash(hash, "DupCompare")) && sv != &PL_sv_undef) {
2169
 
#ifdef DB_DUPSORT
2170
 
                info.dup_compare = dup_compare ;
2171
 
                db->dup_compare = newSVsv(sv) ;
2172
 
                info.flags |= DB_DUP|DB_DUPSORT ;
2173
 
#else
2174
 
                croak("DupCompare needs Berkeley DB 2.5.9 or later") ;
2175
 
#endif
2176
 
            }
2177
 
            RETVAL = my_db_open(db, ref, ref_dbenv, dbenv, txn, file, subname, DB_HASH, flags, mode, &info) ;
2178
 
            Trace(("_db_open_hash end\n")) ;
2179
 
        }
2180
 
        OUTPUT:
2181
 
            RETVAL
2182
 
 
2183
 
 
2184
 
HV *
2185
 
db_stat(db, flags=0)
2186
 
        int                     flags
2187
 
        BerkeleyDB::Common      db
2188
 
        HV *                    RETVAL = NULL ;
2189
 
        INIT:
2190
 
          ckActive_Database(db->active) ;
2191
 
        CODE:
2192
 
        {
2193
 
#if DB_VERSION_MAJOR == 2
2194
 
            softCrash("$db->db_stat for a Hash needs Berkeley DB 3.x or better") ;
2195
 
#else
2196
 
            DB_HASH_STAT *      stat ;
2197
 
#ifdef AT_LEAST_DB_3_3
2198
 
            db->Status = ((db->dbp)->stat)(db->dbp, &stat, flags) ;
2199
 
#else
2200
 
            db->Status = ((db->dbp)->stat)(db->dbp, &stat, safemalloc, flags) ;
2201
 
#endif
2202
 
            if (db->Status == 0) {
2203
 
                RETVAL = (HV*)sv_2mortal((SV*)newHV()) ;
2204
 
                hv_store_iv(RETVAL, "hash_magic", stat->hash_magic) ;
2205
 
                hv_store_iv(RETVAL, "hash_version", stat->hash_version);
2206
 
                hv_store_iv(RETVAL, "hash_pagesize", stat->hash_pagesize);
2207
 
#ifdef AT_LEAST_DB_3_1
2208
 
                hv_store_iv(RETVAL, "hash_nkeys", stat->hash_nkeys);
2209
 
                hv_store_iv(RETVAL, "hash_ndata", stat->hash_ndata);
2210
 
#else
2211
 
                hv_store_iv(RETVAL, "hash_nrecs", stat->hash_nrecs);
2212
 
#endif
2213
 
#ifndef AT_LEAST_DB_3_1
2214
 
                hv_store_iv(RETVAL, "hash_nelem", stat->hash_nelem);
2215
 
#endif
2216
 
                hv_store_iv(RETVAL, "hash_ffactor", stat->hash_ffactor);
2217
 
                hv_store_iv(RETVAL, "hash_buckets", stat->hash_buckets);
2218
 
                hv_store_iv(RETVAL, "hash_free", stat->hash_free);
2219
 
                hv_store_iv(RETVAL, "hash_bfree", stat->hash_bfree);
2220
 
                hv_store_iv(RETVAL, "hash_bigpages", stat->hash_bigpages);
2221
 
                hv_store_iv(RETVAL, "hash_big_bfree", stat->hash_big_bfree);
2222
 
                hv_store_iv(RETVAL, "hash_overflows", stat->hash_overflows);
2223
 
                hv_store_iv(RETVAL, "hash_ovfl_free", stat->hash_ovfl_free);
2224
 
                hv_store_iv(RETVAL, "hash_dup", stat->hash_dup);
2225
 
                hv_store_iv(RETVAL, "hash_dup_free", stat->hash_dup_free);
2226
 
#if DB_VERSION_MAJOR >= 3
2227
 
                hv_store_iv(RETVAL, "hash_metaflags", stat->hash_metaflags);
2228
 
#endif
2229
 
                safefree(stat) ;
2230
 
            }
2231
 
#endif
2232
 
        }
2233
 
        OUTPUT:
2234
 
            RETVAL
2235
 
 
2236
 
 
2237
 
MODULE = BerkeleyDB::Unknown    PACKAGE = BerkeleyDB::Unknown   PREFIX = hash_
2238
 
 
2239
 
void
2240
 
_db_open_unknown(ref)
2241
 
        SV *            ref
2242
 
        PPCODE:
2243
 
        {
2244
 
            HV *                hash ;
2245
 
            SV *                sv ;
2246
 
            DB_INFO             info ;
2247
 
            BerkeleyDB__Env     dbenv = NULL;
2248
 
            SV *                ref_dbenv = NULL;
2249
 
            const char *        file = NULL ;
2250
 
            const char *        subname = NULL ;
2251
 
            int                 flags = 0 ;
2252
 
            int                 mode = 0 ;
2253
 
            BerkeleyDB          db ;
2254
 
            BerkeleyDB          RETVAL ;
2255
 
            BerkeleyDB__Txn     txn = NULL ;
2256
 
            static char *               Names[] = {"", "Btree", "Hash", "Recno"} ;
2257
 
 
2258
 
            hash = (HV*) SvRV(ref) ;
2259
 
            SetValue_pv(file, "Filename", char *) ;
2260
 
            SetValue_pv(subname, "Subname", char *) ;
2261
 
            SetValue_ov(txn, "Txn", BerkeleyDB__Txn) ;
2262
 
            SetValue_ov(dbenv, "Env", BerkeleyDB__Env) ;
2263
 
            ref_dbenv = sv ;
2264
 
            SetValue_iv(flags, "Flags") ;
2265
 
            SetValue_iv(mode, "Mode") ;
2266
 
 
2267
 
            Zero(&info, 1, DB_INFO) ;
2268
 
            SetValue_iv(info.db_cachesize, "Cachesize") ;
2269
 
            SetValue_iv(info.db_lorder, "Lorder") ;
2270
 
            SetValue_iv(info.db_pagesize, "Pagesize") ;
2271
 
            SetValue_iv(info.h_ffactor, "Ffactor") ;
2272
 
            SetValue_iv(info.h_nelem, "Nelem") ;
2273
 
            SetValue_iv(info.flags, "Property") ;
2274
 
            ZMALLOC(db, BerkeleyDB_type) ;
2275
 
 
2276
 
            RETVAL = my_db_open(db, ref, ref_dbenv, dbenv, txn, file, subname, DB_UNKNOWN, flags, mode, &info) ;
2277
 
            XPUSHs(sv_2mortal(newSViv(PTR2IV(RETVAL))));
2278
 
            if (RETVAL)
2279
 
                XPUSHs(sv_2mortal(newSVpv(Names[RETVAL->type], 0))) ;
2280
 
            else
2281
 
                XPUSHs(sv_2mortal(newSViv((IV)NULL)));
2282
 
        }
2283
 
 
2284
 
 
2285
 
 
2286
 
MODULE = BerkeleyDB::Btree      PACKAGE = BerkeleyDB::Btree     PREFIX = btree_
2287
 
 
2288
 
BerkeleyDB::Btree::Raw
2289
 
_db_open_btree(self, ref)
2290
 
        char *          self
2291
 
        SV *            ref
2292
 
        CODE:
2293
 
        {
2294
 
            HV *                hash ;
2295
 
            SV *                sv ;
2296
 
            DB_INFO             info ;
2297
 
            BerkeleyDB__Env     dbenv = NULL;
2298
 
            SV *                ref_dbenv = NULL;
2299
 
            const char *        file = NULL ;
2300
 
            const char *        subname = NULL ;
2301
 
            int                 flags = 0 ;
2302
 
            int                 mode = 0 ;
2303
 
            BerkeleyDB          db ;
2304
 
            BerkeleyDB__Txn     txn = NULL ;
2305
 
 
2306
 
            Trace(("In _db_open_btree\n"));
2307
 
            hash = (HV*) SvRV(ref) ;
2308
 
            SetValue_pv(file, "Filename", char*) ;
2309
 
            SetValue_pv(subname, "Subname", char *) ;
2310
 
            SetValue_ov(txn, "Txn", BerkeleyDB__Txn) ;
2311
 
            SetValue_ov(dbenv, "Env", BerkeleyDB__Env) ;
2312
 
            ref_dbenv = sv ;
2313
 
            SetValue_iv(flags, "Flags") ;
2314
 
            SetValue_iv(mode, "Mode") ;
2315
 
 
2316
 
            Zero(&info, 1, DB_INFO) ;
2317
 
            SetValue_iv(info.db_cachesize, "Cachesize") ;
2318
 
            SetValue_iv(info.db_lorder, "Lorder") ;
2319
 
            SetValue_iv(info.db_pagesize, "Pagesize") ;
2320
 
            SetValue_iv(info.bt_minkey, "Minkey") ;
2321
 
            SetValue_iv(info.flags, "Property") ;
2322
 
            ZMALLOC(db, BerkeleyDB_type) ;
2323
 
            if ((sv = readHash(hash, "Compare")) && sv != &PL_sv_undef) {
2324
 
                Trace(("    Parsed Compare callback\n"));
2325
 
                info.bt_compare = btree_compare ;
2326
 
                db->compare = newSVsv(sv) ;
2327
 
            }
2328
 
            /* DB_DUPSORT was introduced in DB 2.5.9 */
2329
 
            if ((sv = readHash(hash, "DupCompare")) && sv != &PL_sv_undef) {
2330
 
#ifdef DB_DUPSORT
2331
 
                Trace(("    Parsed DupCompare callback\n"));
2332
 
                info.dup_compare = dup_compare ;
2333
 
                db->dup_compare = newSVsv(sv) ;
2334
 
                info.flags |= DB_DUP|DB_DUPSORT ;
2335
 
#else
2336
 
                softCrash("DupCompare needs Berkeley DB 2.5.9 or later") ;
2337
 
#endif
2338
 
            }
2339
 
            if ((sv = readHash(hash, "Prefix")) && sv != &PL_sv_undef) {
2340
 
                Trace(("    Parsed Prefix callback\n"));
2341
 
                info.bt_prefix = btree_prefix ;
2342
 
                db->prefix = newSVsv(sv) ;
2343
 
            }
2344
 
 
2345
 
            RETVAL = my_db_open(db, ref, ref_dbenv, dbenv, txn, file, subname, DB_BTREE, flags, mode, &info) ;
2346
 
        }
2347
 
        OUTPUT:
2348
 
            RETVAL
2349
 
 
2350
 
 
2351
 
HV *
2352
 
db_stat(db, flags=0)
2353
 
        int                     flags
2354
 
        BerkeleyDB::Common      db
2355
 
        HV *                    RETVAL = NULL ;
2356
 
        INIT:
2357
 
          ckActive_Database(db->active) ;
2358
 
        CODE:
2359
 
        {
2360
 
            DB_BTREE_STAT *     stat ;
2361
 
#ifdef AT_LEAST_DB_3_3
2362
 
            db->Status = ((db->dbp)->stat)(db->dbp, &stat, flags) ;
2363
 
#else
2364
 
            db->Status = ((db->dbp)->stat)(db->dbp, &stat, safemalloc, flags) ;
2365
 
#endif
2366
 
            if (db->Status == 0) {
2367
 
                RETVAL = (HV*)sv_2mortal((SV*)newHV()) ;
2368
 
                hv_store_iv(RETVAL, "bt_magic", stat->bt_magic);
2369
 
                hv_store_iv(RETVAL, "bt_version", stat->bt_version);
2370
 
#if DB_VERSION_MAJOR > 2
2371
 
                hv_store_iv(RETVAL, "bt_metaflags", stat->bt_metaflags) ;
2372
 
                hv_store_iv(RETVAL, "bt_flags", stat->bt_metaflags) ;
2373
 
#else
2374
 
                hv_store_iv(RETVAL, "bt_flags", stat->bt_flags) ;
2375
 
#endif
2376
 
                hv_store_iv(RETVAL, "bt_maxkey", stat->bt_maxkey) ;
2377
 
                hv_store_iv(RETVAL, "bt_minkey", stat->bt_minkey);
2378
 
                hv_store_iv(RETVAL, "bt_re_len", stat->bt_re_len);
2379
 
                hv_store_iv(RETVAL, "bt_re_pad", stat->bt_re_pad);
2380
 
                hv_store_iv(RETVAL, "bt_pagesize", stat->bt_pagesize);
2381
 
                hv_store_iv(RETVAL, "bt_levels", stat->bt_levels);
2382
 
#ifdef AT_LEAST_DB_3_1
2383
 
                hv_store_iv(RETVAL, "bt_nkeys", stat->bt_nkeys);
2384
 
                hv_store_iv(RETVAL, "bt_ndata", stat->bt_ndata);
2385
 
#else
2386
 
                hv_store_iv(RETVAL, "bt_nrecs", stat->bt_nrecs);
2387
 
#endif
2388
 
                hv_store_iv(RETVAL, "bt_int_pg", stat->bt_int_pg);
2389
 
                hv_store_iv(RETVAL, "bt_leaf_pg", stat->bt_leaf_pg);
2390
 
                hv_store_iv(RETVAL, "bt_dup_pg", stat->bt_dup_pg);
2391
 
                hv_store_iv(RETVAL, "bt_over_pg", stat->bt_over_pg);
2392
 
                hv_store_iv(RETVAL, "bt_free", stat->bt_free);
2393
 
#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
2394
 
                hv_store_iv(RETVAL, "bt_freed", stat->bt_freed);
2395
 
                hv_store_iv(RETVAL, "bt_pfxsaved", stat->bt_pfxsaved);
2396
 
                hv_store_iv(RETVAL, "bt_split", stat->bt_split);
2397
 
                hv_store_iv(RETVAL, "bt_rootsplit", stat->bt_rootsplit);
2398
 
                hv_store_iv(RETVAL, "bt_fastsplit", stat->bt_fastsplit);
2399
 
                hv_store_iv(RETVAL, "bt_added", stat->bt_added);
2400
 
                hv_store_iv(RETVAL, "bt_deleted", stat->bt_deleted);
2401
 
                hv_store_iv(RETVAL, "bt_get", stat->bt_get);
2402
 
                hv_store_iv(RETVAL, "bt_cache_hit", stat->bt_cache_hit);
2403
 
                hv_store_iv(RETVAL, "bt_cache_miss", stat->bt_cache_miss);
2404
 
#endif
2405
 
                hv_store_iv(RETVAL, "bt_int_pgfree", stat->bt_int_pgfree);
2406
 
                hv_store_iv(RETVAL, "bt_leaf_pgfree", stat->bt_leaf_pgfree);
2407
 
                hv_store_iv(RETVAL, "bt_dup_pgfree", stat->bt_dup_pgfree);
2408
 
                hv_store_iv(RETVAL, "bt_over_pgfree", stat->bt_over_pgfree);
2409
 
                safefree(stat) ;
2410
 
            }
2411
 
        }
2412
 
        OUTPUT:
2413
 
            RETVAL
2414
 
 
2415
 
 
2416
 
MODULE = BerkeleyDB::Recno      PACKAGE = BerkeleyDB::Recno     PREFIX = recno_
2417
 
 
2418
 
BerkeleyDB::Recno::Raw
2419
 
_db_open_recno(self, ref)
2420
 
        char *          self
2421
 
        SV *            ref
2422
 
        CODE:
2423
 
        {
2424
 
            HV *                hash ;
2425
 
            SV *                sv ;
2426
 
            DB_INFO             info ;
2427
 
            BerkeleyDB__Env     dbenv = NULL;
2428
 
            SV *                ref_dbenv = NULL;
2429
 
            const char *        file = NULL ;
2430
 
            const char *        subname = NULL ;
2431
 
            int                 flags = 0 ;
2432
 
            int                 mode = 0 ;
2433
 
            BerkeleyDB          db ;
2434
 
            BerkeleyDB__Txn     txn = NULL ;
2435
 
 
2436
 
            hash = (HV*) SvRV(ref) ;
2437
 
            SetValue_pv(file, "Fname", char*) ;
2438
 
            SetValue_ov(dbenv, "Env", BerkeleyDB__Env) ;
2439
 
            ref_dbenv = sv ;
2440
 
            SetValue_ov(txn, "Txn", BerkeleyDB__Txn) ;
2441
 
            SetValue_iv(flags, "Flags") ;
2442
 
            SetValue_iv(mode, "Mode") ;
2443
 
 
2444
 
            Zero(&info, 1, DB_INFO) ;
2445
 
            SetValue_iv(info.db_cachesize, "Cachesize") ;
2446
 
            SetValue_iv(info.db_lorder, "Lorder") ;
2447
 
            SetValue_iv(info.db_pagesize, "Pagesize") ;
2448
 
            SetValue_iv(info.bt_minkey, "Minkey") ;
2449
 
 
2450
 
            SetValue_iv(info.flags, "Property") ;
2451
 
            SetValue_pv(info.re_source, "Source", char*) ;
2452
 
            if ((sv = readHash(hash, "Len")) && sv != &PL_sv_undef) {
2453
 
                info.re_len = SvIV(sv) ; ;
2454
 
                flagSet_DB2(info.flags, DB_FIXEDLEN) ;
2455
 
            }
2456
 
            if ((sv = readHash(hash, "Delim")) && sv != &PL_sv_undef) {
2457
 
                info.re_delim = SvPOK(sv) ? *SvPV(sv,PL_na) : SvIV(sv) ; ;
2458
 
                flagSet_DB2(info.flags, DB_DELIMITER) ;
2459
 
            }
2460
 
            if ((sv = readHash(hash, "Pad")) && sv != &PL_sv_undef) {
2461
 
                info.re_pad = (u_int32_t)SvPOK(sv) ? *SvPV(sv,PL_na) : SvIV(sv) ; ;
2462
 
                flagSet_DB2(info.flags, DB_PAD) ;
2463
 
            }
2464
 
            ZMALLOC(db, BerkeleyDB_type) ;
2465
 
#ifdef ALLOW_RECNO_OFFSET
2466
 
            SetValue_iv(db->array_base, "ArrayBase") ;
2467
 
            db->array_base = (db->array_base == 0 ? 1 : 0) ;
2468
 
#endif /* ALLOW_RECNO_OFFSET */
2469
 
 
2470
 
            RETVAL = my_db_open(db, ref, ref_dbenv, dbenv, txn, file, subname, DB_RECNO, flags, mode, &info) ;
2471
 
        }
2472
 
        OUTPUT:
2473
 
            RETVAL
2474
 
 
2475
 
 
2476
 
MODULE = BerkeleyDB::Queue      PACKAGE = BerkeleyDB::Queue     PREFIX = recno_
2477
 
 
2478
 
BerkeleyDB::Queue::Raw
2479
 
_db_open_queue(self, ref)
2480
 
        char *          self
2481
 
        SV *            ref
2482
 
        CODE:
2483
 
        {
2484
 
#ifndef AT_LEAST_DB_3
2485
 
            softCrash("BerkeleyDB::Queue needs Berkeley DB 3.0.x or better");
2486
 
#else
2487
 
            HV *                hash ;
2488
 
            SV *                sv ;
2489
 
            DB_INFO             info ;
2490
 
            BerkeleyDB__Env     dbenv = NULL;
2491
 
            SV *                ref_dbenv = NULL;
2492
 
            const char *        file = NULL ;
2493
 
            const char *        subname = NULL ;
2494
 
            int                 flags = 0 ;
2495
 
            int                 mode = 0 ;
2496
 
            BerkeleyDB          db ;
2497
 
            BerkeleyDB__Txn     txn = NULL ;
2498
 
 
2499
 
            hash = (HV*) SvRV(ref) ;
2500
 
            SetValue_pv(file, "Fname", char*) ;
2501
 
            SetValue_ov(dbenv, "Env", BerkeleyDB__Env) ;
2502
 
            ref_dbenv = sv ;
2503
 
            SetValue_ov(txn, "Txn", BerkeleyDB__Txn) ;
2504
 
            SetValue_iv(flags, "Flags") ;
2505
 
            SetValue_iv(mode, "Mode") ;
2506
 
 
2507
 
            Zero(&info, 1, DB_INFO) ;
2508
 
            SetValue_iv(info.db_cachesize, "Cachesize") ;
2509
 
            SetValue_iv(info.db_lorder, "Lorder") ;
2510
 
            SetValue_iv(info.db_pagesize, "Pagesize") ;
2511
 
            SetValue_iv(info.bt_minkey, "Minkey") ;
2512
 
            SetValue_iv(info.q_extentsize, "ExtentSize") ;
2513
 
 
2514
 
 
2515
 
            SetValue_iv(info.flags, "Property") ;
2516
 
            if ((sv = readHash(hash, "Len")) && sv != &PL_sv_undef) {
2517
 
                info.re_len = SvIV(sv) ; ;
2518
 
                flagSet_DB2(info.flags, DB_FIXEDLEN) ;
2519
 
            }
2520
 
            if ((sv = readHash(hash, "Pad")) && sv != &PL_sv_undef) {
2521
 
                info.re_pad = (u_int32_t)SvPOK(sv) ? *SvPV(sv,PL_na) : SvIV(sv) ; ;
2522
 
                flagSet_DB2(info.flags, DB_PAD) ;
2523
 
            }
2524
 
            ZMALLOC(db, BerkeleyDB_type) ;
2525
 
#ifdef ALLOW_RECNO_OFFSET
2526
 
            SetValue_iv(db->array_base, "ArrayBase") ;
2527
 
            db->array_base = (db->array_base == 0 ? 1 : 0) ;
2528
 
#endif /* ALLOW_RECNO_OFFSET */
2529
 
 
2530
 
            RETVAL = my_db_open(db, ref, ref_dbenv, dbenv, txn, file, subname, DB_QUEUE, flags, mode, &info) ;
2531
 
#endif
2532
 
        }
2533
 
        OUTPUT:
2534
 
            RETVAL
2535
 
 
2536
 
HV *
2537
 
db_stat(db, flags=0)
2538
 
        int                     flags
2539
 
        BerkeleyDB::Common      db
2540
 
        HV *                    RETVAL = NULL ;
2541
 
        INIT:
2542
 
          ckActive_Database(db->active) ;
2543
 
        CODE:
2544
 
        {
2545
 
#if DB_VERSION_MAJOR == 2
2546
 
            softCrash("$db->db_stat for a Queue needs Berkeley DB 3.x or better") ;
2547
 
#else /* Berkeley DB 3, or better */
2548
 
            DB_QUEUE_STAT *     stat ;
2549
 
#ifdef AT_LEAST_DB_3_3
2550
 
            db->Status = ((db->dbp)->stat)(db->dbp, &stat, flags) ;
2551
 
#else
2552
 
            db->Status = ((db->dbp)->stat)(db->dbp, &stat, safemalloc, flags) ;
2553
 
#endif
2554
 
            if (db->Status == 0) {
2555
 
                RETVAL = (HV*)sv_2mortal((SV*)newHV()) ;
2556
 
                hv_store_iv(RETVAL, "qs_magic", stat->qs_magic) ;
2557
 
                hv_store_iv(RETVAL, "qs_version", stat->qs_version);
2558
 
#ifdef AT_LEAST_DB_3_1
2559
 
                hv_store_iv(RETVAL, "qs_nkeys", stat->qs_nkeys);
2560
 
                hv_store_iv(RETVAL, "qs_ndata", stat->qs_ndata);
2561
 
#else
2562
 
                hv_store_iv(RETVAL, "qs_nrecs", stat->qs_nrecs);
2563
 
#endif
2564
 
                hv_store_iv(RETVAL, "qs_pages", stat->qs_pages);
2565
 
                hv_store_iv(RETVAL, "qs_pagesize", stat->qs_pagesize);
2566
 
                hv_store_iv(RETVAL, "qs_pgfree", stat->qs_pgfree);
2567
 
                hv_store_iv(RETVAL, "qs_re_len", stat->qs_re_len);
2568
 
                hv_store_iv(RETVAL, "qs_re_pad", stat->qs_re_pad);
2569
 
#ifdef AT_LEAST_DB_3_2
2570
 
#else
2571
 
                hv_store_iv(RETVAL, "qs_start", stat->qs_start);
2572
 
#endif
2573
 
                hv_store_iv(RETVAL, "qs_first_recno", stat->qs_first_recno);
2574
 
                hv_store_iv(RETVAL, "qs_cur_recno", stat->qs_cur_recno);
2575
 
#if DB_VERSION_MAJOR >= 3
2576
 
                hv_store_iv(RETVAL, "qs_metaflags", stat->qs_metaflags);
2577
 
#endif
2578
 
                safefree(stat) ;
2579
 
            }
2580
 
#endif
2581
 
        }
2582
 
        OUTPUT:
2583
 
            RETVAL
2584
 
 
2585
 
 
2586
 
MODULE = BerkeleyDB::Common  PACKAGE = BerkeleyDB::Common       PREFIX = dab_
2587
 
 
2588
 
 
2589
 
DualType
2590
 
db_close(db,flags=0)
2591
 
        int                     flags
2592
 
        BerkeleyDB::Common      db
2593
 
        INIT:
2594
 
            ckActive_Database(db->active) ;
2595
 
            CurrentDB = db ;
2596
 
        CODE:
2597
 
            Trace(("BerkeleyDB::Common::db_close %d\n", db));
2598
 
#ifdef STRICT_CLOSE
2599
 
            if (db->txn)
2600
 
                softCrash("attempted to close a database while a transaction was still open") ;
2601
 
            if (db->open_cursors)
2602
 
                softCrash("attempted to close a database with %d open cursor(s)",
2603
 
                                db->open_cursors) ;
2604
 
#endif /* STRICT_CLOSE */
2605
 
            RETVAL =  db->Status = ((db->dbp)->close)(db->dbp, flags) ;
2606
 
            if (db->parent_env && db->parent_env->open_dbs)
2607
 
                -- db->parent_env->open_dbs ;
2608
 
            db->active = FALSE ;
2609
 
            hash_delete("BerkeleyDB::Term::Db", (char *)db) ;
2610
 
            -- db->open_cursors ;
2611
 
            Trace(("end of BerkeleyDB::Common::db_close\n"));
2612
 
        OUTPUT:
2613
 
            RETVAL
2614
 
 
2615
 
void
2616
 
dab__DESTROY(db)
2617
 
        BerkeleyDB::Common      db
2618
 
        CODE:
2619
 
          CurrentDB = db ;
2620
 
          Trace(("In BerkeleyDB::Common::_DESTROY db %d dirty=%d\n", db, PL_dirty)) ;
2621
 
          destroyDB(db) ;
2622
 
          Trace(("End of BerkeleyDB::Common::DESTROY \n")) ;
2623
 
 
2624
 
#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
2625
 
#define db_cursor(db, txn, cur,flags)  ((db->dbp)->cursor)(db->dbp, txn, cur)
2626
 
#else
2627
 
#define db_cursor(db, txn, cur,flags)  ((db->dbp)->cursor)(db->dbp, txn, cur,flags)
2628
 
#endif
2629
 
BerkeleyDB::Cursor::Raw
2630
 
_db_cursor(db, flags=0)
2631
 
        u_int32_t               flags
2632
 
        BerkeleyDB::Common      db
2633
 
        BerkeleyDB::Cursor      RETVAL = NULL ;
2634
 
        INIT:
2635
 
            ckActive_Database(db->active) ;
2636
 
        CODE:
2637
 
        {
2638
 
          DBC *         cursor ;
2639
 
          CurrentDB = db ;
2640
 
          if ((db->Status = db_cursor(db, db->txn, &cursor, flags)) == 0){
2641
 
              ZMALLOC(RETVAL, BerkeleyDB__Cursor_type) ;
2642
 
              db->open_cursors ++ ;
2643
 
              RETVAL->parent_db  = db ;
2644
 
              RETVAL->cursor  = cursor ;
2645
 
              RETVAL->dbp     = db->dbp ;
2646
 
              RETVAL->txn     = db->txn ;
2647
 
              RETVAL->type    = db->type ;
2648
 
              RETVAL->recno_or_queue    = db->recno_or_queue ;
2649
 
              RETVAL->filename    = my_strdup(db->filename) ;
2650
 
              RETVAL->compare = db->compare ;
2651
 
              RETVAL->dup_compare = db->dup_compare ;
2652
 
#ifdef AT_LEAST_DB_3_3
2653
 
              RETVAL->associated = db->associated ;
2654
 
              RETVAL->secondary_db  = db->secondary_db;
2655
 
#endif
2656
 
              RETVAL->prefix  = db->prefix ;
2657
 
              RETVAL->hash    = db->hash ;
2658
 
              RETVAL->partial = db->partial ;
2659
 
              RETVAL->doff    = db->doff ;
2660
 
              RETVAL->dlen    = db->dlen ;
2661
 
              RETVAL->active  = TRUE ;
2662
 
#ifdef ALLOW_RECNO_OFFSET
2663
 
              RETVAL->array_base  = db->array_base ;
2664
 
#endif /* ALLOW_RECNO_OFFSET */
2665
 
#ifdef DBM_FILTERING
2666
 
              RETVAL->filtering   = FALSE ;
2667
 
              RETVAL->filter_fetch_key    = db->filter_fetch_key ;
2668
 
              RETVAL->filter_store_key    = db->filter_store_key ;
2669
 
              RETVAL->filter_fetch_value  = db->filter_fetch_value ;
2670
 
              RETVAL->filter_store_value  = db->filter_store_value ;
2671
 
#endif
2672
 
              /* RETVAL->info ; */
2673
 
              hash_store_iv("BerkeleyDB::Term::Cursor", (char *)RETVAL, 1) ;
2674
 
          }
2675
 
        }
2676
 
        OUTPUT:
2677
 
          RETVAL
2678
 
 
2679
 
BerkeleyDB::Cursor::Raw
2680
 
_db_join(db, cursors, flags=0)
2681
 
        u_int32_t               flags
2682
 
        BerkeleyDB::Common      db
2683
 
        AV *                    cursors
2684
 
        BerkeleyDB::Cursor      RETVAL = NULL ;
2685
 
        INIT:
2686
 
            ckActive_Database(db->active) ;
2687
 
        CODE:
2688
 
        {
2689
 
#if DB_VERSION_MAJOR == 2 && (DB_VERSION_MINOR < 5 || (DB_VERSION_MINOR == 5 && DB_VERSION_PATCH < 2))
2690
 
            softCrash("join needs Berkeley DB 2.5.2 or later") ;
2691
 
#else /* Berkeley DB >= 2.5.2 */
2692
 
          DBC *         join_cursor ;
2693
 
          DBC **        cursor_list ;
2694
 
          I32           count = av_len(cursors) + 1 ;
2695
 
          int           i ;
2696
 
          CurrentDB = db ;
2697
 
          if (count < 1 )
2698
 
              softCrash("db_join: No cursors in parameter list") ;
2699
 
          cursor_list = (DBC **)safemalloc(sizeof(DBC*) * (count + 1));
2700
 
          for (i = 0 ; i < count ; ++i) {
2701
 
              SV * obj = (SV*) * av_fetch(cursors, i, FALSE) ;
2702
 
              IV tmp = SvIV(getInnerObject(obj)) ;
2703
 
              BerkeleyDB__Cursor cur = INT2PTR(BerkeleyDB__Cursor, tmp);
2704
 
              cursor_list[i] = cur->cursor ;
2705
 
          }
2706
 
          cursor_list[i] = NULL ;
2707
 
#if DB_VERSION_MAJOR == 2
2708
 
          if ((db->Status = ((db->dbp)->join)(db->dbp, cursor_list, flags, &join_cursor)) == 0){
2709
 
#else
2710
 
          if ((db->Status = ((db->dbp)->join)(db->dbp, cursor_list, &join_cursor, flags)) == 0){
2711
 
#endif
2712
 
              ZMALLOC(RETVAL, BerkeleyDB__Cursor_type) ;
2713
 
              db->open_cursors ++ ;
2714
 
              RETVAL->parent_db  = db ;
2715
 
              RETVAL->cursor  = join_cursor ;
2716
 
              RETVAL->dbp     = db->dbp ;
2717
 
              RETVAL->type    = db->type ;
2718
 
              RETVAL->filename    = my_strdup(db->filename) ;
2719
 
              RETVAL->compare = db->compare ;
2720
 
              RETVAL->dup_compare = db->dup_compare ;
2721
 
#ifdef AT_LEAST_DB_3_3
2722
 
              RETVAL->associated = db->associated ;
2723
 
              RETVAL->secondary_db  = db->secondary_db;
2724
 
#endif
2725
 
              RETVAL->prefix  = db->prefix ;
2726
 
              RETVAL->hash    = db->hash ;
2727
 
              RETVAL->partial = db->partial ;
2728
 
              RETVAL->doff    = db->doff ;
2729
 
              RETVAL->dlen    = db->dlen ;
2730
 
              RETVAL->active  = TRUE ;
2731
 
#ifdef ALLOW_RECNO_OFFSET
2732
 
              RETVAL->array_base  = db->array_base ;
2733
 
#endif /* ALLOW_RECNO_OFFSET */
2734
 
#ifdef DBM_FILTERING
2735
 
              RETVAL->filtering   = FALSE ;
2736
 
              RETVAL->filter_fetch_key    = db->filter_fetch_key ;
2737
 
              RETVAL->filter_store_key    = db->filter_store_key ;
2738
 
              RETVAL->filter_fetch_value  = db->filter_fetch_value ;
2739
 
              RETVAL->filter_store_value  = db->filter_store_value ;
2740
 
#endif
2741
 
              /* RETVAL->info ; */
2742
 
              hash_store_iv("BerkeleyDB::Term::Cursor", (char *)RETVAL, 1) ;
2743
 
          }
2744
 
          safefree(cursor_list) ;
2745
 
#endif /* Berkeley DB >= 2.5.2 */
2746
 
        }
2747
 
        OUTPUT:
2748
 
          RETVAL
2749
 
 
2750
 
int
2751
 
ArrayOffset(db)
2752
 
        BerkeleyDB::Common      db
2753
 
        INIT:
2754
 
            ckActive_Database(db->active) ;
2755
 
        CODE:
2756
 
#ifdef ALLOW_RECNO_OFFSET
2757
 
            RETVAL = db->array_base ? 0 : 1 ;
2758
 
#else
2759
 
            RETVAL = 0 ;
2760
 
#endif /* ALLOW_RECNO_OFFSET */
2761
 
        OUTPUT:
2762
 
            RETVAL
2763
 
 
2764
 
int
2765
 
type(db)
2766
 
        BerkeleyDB::Common      db
2767
 
        INIT:
2768
 
            ckActive_Database(db->active) ;
2769
 
        CODE:
2770
 
            RETVAL = db->type ;
2771
 
        OUTPUT:
2772
 
            RETVAL
2773
 
 
2774
 
int
2775
 
byteswapped(db)
2776
 
        BerkeleyDB::Common      db
2777
 
        INIT:
2778
 
            ckActive_Database(db->active) ;
2779
 
        CODE:
2780
 
#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
2781
 
            softCrash("byteswapped needs Berkeley DB 2.5 or later") ;
2782
 
#else
2783
 
#if DB_VERSION_MAJOR == 2
2784
 
            RETVAL = db->dbp->byteswapped ;
2785
 
#else
2786
 
#ifdef AT_LEAST_DB_3_3
2787
 
            db->dbp->get_byteswapped(db->dbp, &RETVAL) ;
2788
 
#else
2789
 
            RETVAL = db->dbp->get_byteswapped(db->dbp) ;
2790
 
#endif
2791
 
#endif
2792
 
#endif
2793
 
        OUTPUT:
2794
 
            RETVAL
2795
 
 
2796
 
DualType
2797
 
status(db)
2798
 
        BerkeleyDB::Common      db
2799
 
        CODE:
2800
 
            RETVAL =  db->Status ;
2801
 
        OUTPUT:
2802
 
            RETVAL
2803
 
 
2804
 
#ifdef DBM_FILTERING
2805
 
 
2806
 
#define setFilter(ftype)                                \
2807
 
        {                                               \
2808
 
            if (db->ftype)                              \
2809
 
                RETVAL = sv_mortalcopy(db->ftype) ;     \
2810
 
            ST(0) = RETVAL ;                            \
2811
 
            if (db->ftype && (code == &PL_sv_undef)) {  \
2812
 
                SvREFCNT_dec(db->ftype) ;               \
2813
 
                db->ftype = NULL ;                      \
2814
 
            }                                           \
2815
 
            else if (code) {                            \
2816
 
                if (db->ftype)                          \
2817
 
                    sv_setsv(db->ftype, code) ;         \
2818
 
                else                                    \
2819
 
                    db->ftype = newSVsv(code) ;         \
2820
 
            }                                           \
2821
 
        }
2822
 
 
2823
 
 
2824
 
SV *
2825
 
filter_fetch_key(db, code)
2826
 
        BerkeleyDB::Common              db
2827
 
        SV *            code
2828
 
        SV *            RETVAL = &PL_sv_undef ;
2829
 
        CODE:
2830
 
            DBM_setFilter(db->filter_fetch_key, code) ;
2831
 
 
2832
 
SV *
2833
 
filter_store_key(db, code)
2834
 
        BerkeleyDB::Common              db
2835
 
        SV *            code
2836
 
        SV *            RETVAL = &PL_sv_undef ;
2837
 
        CODE:
2838
 
            DBM_setFilter(db->filter_store_key, code) ;
2839
 
 
2840
 
SV *
2841
 
filter_fetch_value(db, code)
2842
 
        BerkeleyDB::Common              db
2843
 
        SV *            code
2844
 
        SV *            RETVAL = &PL_sv_undef ;
2845
 
        CODE:
2846
 
            DBM_setFilter(db->filter_fetch_value, code) ;
2847
 
 
2848
 
SV *
2849
 
filter_store_value(db, code)
2850
 
        BerkeleyDB::Common              db
2851
 
        SV *            code
2852
 
        SV *            RETVAL = &PL_sv_undef ;
2853
 
        CODE:
2854
 
            DBM_setFilter(db->filter_store_value, code) ;
2855
 
 
2856
 
#endif /* DBM_FILTERING */
2857
 
 
2858
 
void
2859
 
partial_set(db, offset, length)
2860
 
        BerkeleyDB::Common      db
2861
 
        u_int32_t               offset
2862
 
        u_int32_t               length
2863
 
        INIT:
2864
 
            ckActive_Database(db->active) ;
2865
 
        PPCODE:
2866
 
            if (GIMME == G_ARRAY) {
2867
 
                XPUSHs(sv_2mortal(newSViv(db->partial == DB_DBT_PARTIAL))) ;
2868
 
                XPUSHs(sv_2mortal(newSViv(db->doff))) ;
2869
 
                XPUSHs(sv_2mortal(newSViv(db->dlen))) ;
2870
 
            }
2871
 
            db->partial = DB_DBT_PARTIAL ;
2872
 
            db->doff    = offset ;
2873
 
            db->dlen    = length ;
2874
 
 
2875
 
 
2876
 
void
2877
 
partial_clear(db)
2878
 
        BerkeleyDB::Common      db
2879
 
        INIT:
2880
 
            ckActive_Database(db->active) ;
2881
 
        PPCODE:
2882
 
            if (GIMME == G_ARRAY) {
2883
 
                XPUSHs(sv_2mortal(newSViv(db->partial == DB_DBT_PARTIAL))) ;
2884
 
                XPUSHs(sv_2mortal(newSViv(db->doff))) ;
2885
 
                XPUSHs(sv_2mortal(newSViv(db->dlen))) ;
2886
 
            }
2887
 
            db->partial =
2888
 
            db->doff    =
2889
 
            db->dlen    = 0 ;
2890
 
 
2891
 
 
2892
 
#define db_del(db, key, flags)  \
2893
 
        (db->Status = ((db->dbp)->del)(db->dbp, db->txn, &key, flags))
2894
 
DualType
2895
 
db_del(db, key, flags=0)
2896
 
        u_int           flags
2897
 
        BerkeleyDB::Common      db
2898
 
        DBTKEY          key
2899
 
        INIT:
2900
 
            Trace(("db_del db[%p] in [%p] txn[%p] key[%.*s] flags[%d]\n", db->dbp, db, db->txn, key.size, key.data, flags)) ;
2901
 
            ckActive_Database(db->active) ;
2902
 
            CurrentDB = db ;
2903
 
 
2904
 
 
2905
 
#ifdef AT_LEAST_DB_3
2906
 
#  ifdef AT_LEAST_DB_3_2
2907
 
#    define writeToKey() (flagSet(DB_CONSUME)||flagSet(DB_CONSUME_WAIT)||flagSet(DB_GET_BOTH)||flagSet(DB_SET_RECNO))
2908
 
#  else
2909
 
#    define writeToKey() (flagSet(DB_CONSUME)||flagSet(DB_GET_BOTH)||flagSet(DB_SET_RECNO))
2910
 
#  endif
2911
 
#else
2912
 
#define writeToKey() (flagSet(DB_GET_BOTH)||flagSet(DB_SET_RECNO))
2913
 
#endif
2914
 
#define db_get(db, key, data, flags)   \
2915
 
        (db->Status = ((db->dbp)->get)(db->dbp, db->txn, &key, &data, flags))
2916
 
DualType
2917
 
db_get(db, key, data, flags=0)
2918
 
        u_int           flags
2919
 
        BerkeleyDB::Common      db
2920
 
        DBTKEY_B        key
2921
 
        DBT_OPT         data
2922
 
        CODE:
2923
 
          ckActive_Database(db->active) ;
2924
 
          CurrentDB = db ;
2925
 
          SetPartial(data,db) ;
2926
 
          Trace(("db_get db[%p] in [%p] txn[%p] key [%.*s] flags[%d]\n", db->dbp, db, db->txn, key.size, key.data, flags)) ;
2927
 
          RETVAL = db_get(db, key, data, flags);
2928
 
          Trace(("  RETVAL %d\n", RETVAL));
2929
 
        OUTPUT:
2930
 
          RETVAL
2931
 
          key   if (writeToKey()) OutputKey(ST(1), key) ;
2932
 
          data
2933
 
 
2934
 
#define db_pget(db, key, pkey, data, flags)   \
2935
 
        (db->Status = ((db->dbp)->pget)(db->dbp, db->txn, &key, &pkey, &data, flags))
2936
 
DualType
2937
 
db_pget(db, key, pkey, data, flags=0)
2938
 
        u_int           flags
2939
 
        BerkeleyDB::Common      db
2940
 
        DBTKEY_B        key
2941
 
        DBTKEY_B        pkey = NO_INIT
2942
 
        DBT_OPT         data
2943
 
        CODE:
2944
 
#ifndef AT_LEAST_DB_3_3
2945
 
          softCrash("db_pget needs at least Berkeley DB 3.3");
2946
 
#else
2947
 
          Trace(("db_pget db [%p] in [%p] txn [%p] flags [%d]\n", db->dbp, db, db->txn, flags)) ;
2948
 
          ckActive_Database(db->active) ;
2949
 
          CurrentDB = db ;
2950
 
          SetPartial(data,db) ;
2951
 
          DBT_clear(pkey);
2952
 
          RETVAL = db_pget(db, key, pkey, data, flags);
2953
 
          Trace(("  RETVAL %d\n", RETVAL));
2954
 
#endif
2955
 
        OUTPUT:
2956
 
          RETVAL
2957
 
          key   if (writeToKey()) OutputKey(ST(1), key) ;
2958
 
          pkey
2959
 
          data
2960
 
 
2961
 
#define db_put(db,key,data,flag)        \
2962
 
                (db->Status = (db->dbp->put)(db->dbp,db->txn,&key,&data,flag))
2963
 
DualType
2964
 
db_put(db, key, data, flags=0)
2965
 
        u_int                   flags
2966
 
        BerkeleyDB::Common      db
2967
 
        DBTKEY                  key
2968
 
        DBT                     data
2969
 
        CODE:
2970
 
          ckActive_Database(db->active) ;
2971
 
          CurrentDB = db ;
2972
 
          /* SetPartial(data,db) ; */
2973
 
          Trace(("db_put db[%p] in [%p] txn[%p] key[%.*s] data [%.*s] flags[%d]\n", db->dbp, db, db->txn, key.size, key.data, data.size, data.data, flags)) ;
2974
 
          RETVAL = db_put(db, key, data, flags);
2975
 
          Trace(("  RETVAL %d\n", RETVAL));
2976
 
        OUTPUT:
2977
 
          RETVAL
2978
 
          key   if (flagSet(DB_APPEND)) OutputKey(ST(1), key) ;
2979
 
 
2980
 
#define db_key_range(db, key, range, flags)   \
2981
 
        (db->Status = ((db->dbp)->key_range)(db->dbp, db->txn, &key, &range, flags))
2982
 
DualType
2983
 
db_key_range(db, key, less, equal, greater, flags=0)
2984
 
        u_int32_t       flags
2985
 
        BerkeleyDB::Common      db
2986
 
        DBTKEY_B        key
2987
 
        double          less = 0.0 ;
2988
 
        double          equal = 0.0 ;
2989
 
        double          greater = 0.0 ;
2990
 
        CODE:
2991
 
        {
2992
 
#ifndef AT_LEAST_DB_3_1
2993
 
          softCrash("key_range needs Berkeley DB 3.1.x or later") ;
2994
 
#else
2995
 
          DB_KEY_RANGE range ;
2996
 
          range.less = range.equal = range.greater = 0.0 ;
2997
 
          ckActive_Database(db->active) ;
2998
 
          CurrentDB = db ;
2999
 
          RETVAL = db_key_range(db, key, range, flags);
3000
 
          if (RETVAL == 0) {
3001
 
                less = range.less ;
3002
 
                equal = range.equal;
3003
 
                greater = range.greater;
3004
 
          }
3005
 
#endif
3006
 
        }
3007
 
        OUTPUT:
3008
 
          RETVAL
3009
 
          less
3010
 
          equal
3011
 
          greater
3012
 
 
3013
 
 
3014
 
#define db_fd(d, x)     (db->Status = (db->dbp->fd)(db->dbp, &x))
3015
 
DualType
3016
 
db_fd(db)
3017
 
        BerkeleyDB::Common      db
3018
 
        INIT:
3019
 
          ckActive_Database(db->active) ;
3020
 
        CODE:
3021
 
          CurrentDB = db ;
3022
 
          db_fd(db, RETVAL) ;
3023
 
        OUTPUT:
3024
 
          RETVAL
3025
 
 
3026
 
 
3027
 
#define db_sync(db, fl) (db->Status = (db->dbp->sync)(db->dbp, fl))
3028
 
DualType
3029
 
db_sync(db, flags=0)
3030
 
        u_int                   flags
3031
 
        BerkeleyDB::Common      db
3032
 
        INIT:
3033
 
          ckActive_Database(db->active) ;
3034
 
          CurrentDB = db ;
3035
 
 
3036
 
void
3037
 
_Txn(db, txn=NULL)
3038
 
        BerkeleyDB::Common      db
3039
 
        BerkeleyDB::Txn         txn
3040
 
        INIT:
3041
 
          ckActive_Database(db->active) ;
3042
 
        CODE:
3043
 
           if (txn) {
3044
 
               Trace(("_Txn[%p] in[%p] active [%d]\n", txn->txn, txn, txn->active));
3045
 
               ckActive_Transaction(txn->active) ;
3046
 
               db->txn = txn->txn ;
3047
 
           }
3048
 
           else {
3049
 
               Trace(("_Txn[undef] \n"));
3050
 
               db->txn = NULL ;
3051
 
           }
3052
 
 
3053
 
 
3054
 
#define db_truncate(db, countp, flags)  \
3055
 
        (db->Status = ((db->dbp)->truncate)(db->dbp, db->txn, &countp, flags))
3056
 
DualType
3057
 
truncate(db, countp, flags=0)
3058
 
        BerkeleyDB::Common      db
3059
 
        u_int32_t               countp
3060
 
        u_int32_t               flags
3061
 
        INIT:
3062
 
          ckActive_Database(db->active) ;
3063
 
        CODE:
3064
 
#ifndef AT_LEAST_DB_3_3
3065
 
          softCrash("truncate needs Berkeley DB 3.3 or later") ;
3066
 
#else
3067
 
          CurrentDB = db ;
3068
 
          RETVAL = db_truncate(db, countp, flags);
3069
 
#endif
3070
 
        OUTPUT:
3071
 
          RETVAL
3072
 
          countp
3073
 
 
3074
 
#ifdef AT_LEAST_DB_4_1
3075
 
#  define db_associate(db, sec, cb, flags)\
3076
 
        (db->Status = ((db->dbp)->associate)(db->dbp, NULL, sec->dbp, &cb, flags))
3077
 
#else
3078
 
#  define db_associate(db, sec, cb, flags)\
3079
 
        (db->Status = ((db->dbp)->associate)(db->dbp, sec->dbp, &cb, flags))
3080
 
#endif
3081
 
DualType
3082
 
associate(db, secondary, callback, flags=0)
3083
 
        BerkeleyDB::Common      db
3084
 
        BerkeleyDB::Common      secondary
3085
 
        SV*                     callback
3086
 
        u_int32_t               flags
3087
 
        INIT:
3088
 
          ckActive_Database(db->active) ;
3089
 
        CODE:
3090
 
#ifndef AT_LEAST_DB_3_3
3091
 
          softCrash("associate needs Berkeley DB 3.3 or later") ;
3092
 
#else
3093
 
          CurrentDB = db ;
3094
 
          /* db->associated = newSVsv(callback) ; */
3095
 
          secondary->associated = newSVsv(callback) ;
3096
 
          /* secondary->dbp->app_private = secondary->associated ; */
3097
 
          secondary->secondary_db = TRUE;
3098
 
          RETVAL = db_associate(db, secondary, associate_cb, flags);
3099
 
#endif
3100
 
        OUTPUT:
3101
 
          RETVAL
3102
 
 
3103
 
 
3104
 
MODULE = BerkeleyDB::Cursor              PACKAGE = BerkeleyDB::Cursor   PREFIX = cu_
3105
 
 
3106
 
BerkeleyDB::Cursor::Raw
3107
 
_c_dup(db, flags=0)
3108
 
        u_int32_t               flags
3109
 
        BerkeleyDB::Cursor      db
3110
 
        BerkeleyDB::Cursor      RETVAL = NULL ;
3111
 
        INIT:
3112
 
            CurrentDB = db->parent_db ;
3113
 
            ckActive_Database(db->active) ;
3114
 
        CODE:
3115
 
        {
3116
 
#ifndef AT_LEAST_DB_3
3117
 
          softCrash("c_dup needs at least Berkeley DB 3.0.x");
3118
 
#else
3119
 
          DBC *         newcursor ;
3120
 
          db->Status = ((db->cursor)->c_dup)(db->cursor, &newcursor, flags) ;
3121
 
          if (db->Status == 0){
3122
 
              ZMALLOC(RETVAL, BerkeleyDB__Cursor_type) ;
3123
 
              db->parent_db->open_cursors ++ ;
3124
 
              RETVAL->parent_db  = db->parent_db ;
3125
 
              RETVAL->cursor  = newcursor ;
3126
 
              RETVAL->dbp     = db->dbp ;
3127
 
              RETVAL->type    = db->type ;
3128
 
              RETVAL->recno_or_queue    = db->recno_or_queue ;
3129
 
              RETVAL->filename    = my_strdup(db->filename) ;
3130
 
              RETVAL->compare = db->compare ;
3131
 
              RETVAL->dup_compare = db->dup_compare ;
3132
 
#ifdef AT_LEAST_DB_3_3
3133
 
              RETVAL->associated = db->associated ;
3134
 
#endif
3135
 
              RETVAL->prefix  = db->prefix ;
3136
 
              RETVAL->hash    = db->hash ;
3137
 
              RETVAL->partial = db->partial ;
3138
 
              RETVAL->doff    = db->doff ;
3139
 
              RETVAL->dlen    = db->dlen ;
3140
 
              RETVAL->active  = TRUE ;
3141
 
#ifdef ALLOW_RECNO_OFFSET
3142
 
              RETVAL->array_base  = db->array_base ;
3143
 
#endif /* ALLOW_RECNO_OFFSET */
3144
 
#ifdef DBM_FILTERING
3145
 
              RETVAL->filtering   = FALSE ;
3146
 
              RETVAL->filter_fetch_key    = db->filter_fetch_key ;
3147
 
              RETVAL->filter_store_key    = db->filter_store_key ;
3148
 
              RETVAL->filter_fetch_value  = db->filter_fetch_value ;
3149
 
              RETVAL->filter_store_value  = db->filter_store_value ;
3150
 
#endif /* DBM_FILTERING */
3151
 
              /* RETVAL->info ; */
3152
 
              hash_store_iv("BerkeleyDB::Term::Cursor", (char *)RETVAL, 1) ;
3153
 
          }
3154
 
#endif  
3155
 
        }
3156
 
        OUTPUT:
3157
 
          RETVAL
3158
 
 
3159
 
DualType
3160
 
_c_close(db)
3161
 
    BerkeleyDB::Cursor  db
3162
 
        INIT:
3163
 
          CurrentDB = db->parent_db ;
3164
 
          ckActive_Cursor(db->active) ;
3165
 
          hash_delete("BerkeleyDB::Term::Cursor", (char *)db) ;
3166
 
        CODE:
3167
 
          RETVAL =  db->Status =
3168
 
                  ((db->cursor)->c_close)(db->cursor) ;
3169
 
          db->active = FALSE ;
3170
 
          if (db->parent_db->open_cursors)
3171
 
              -- db->parent_db->open_cursors ;
3172
 
        OUTPUT:
3173
 
          RETVAL
3174
 
 
3175
 
void
3176
 
_DESTROY(db)
3177
 
    BerkeleyDB::Cursor  db
3178
 
        CODE:
3179
 
          CurrentDB = db->parent_db ;
3180
 
          Trace(("In BerkeleyDB::Cursor::_DESTROY db %d dirty=%d active=%d\n", db, PL_dirty, db->active));
3181
 
          hash_delete("BerkeleyDB::Term::Cursor", (char *)db) ;
3182
 
          if (db->active)
3183
 
              ((db->cursor)->c_close)(db->cursor) ;
3184
 
          if (db->parent_db->open_cursors)
3185
 
              -- db->parent_db->open_cursors ;
3186
 
          Safefree(db->filename) ;
3187
 
          Safefree(db) ;
3188
 
          Trace(("End of BerkeleyDB::Cursor::_DESTROY\n")) ;
3189
 
 
3190
 
DualType
3191
 
status(db)
3192
 
        BerkeleyDB::Cursor      db
3193
 
        CODE:
3194
 
            RETVAL =  db->Status ;
3195
 
        OUTPUT:
3196
 
            RETVAL
3197
 
 
3198
 
 
3199
 
#define cu_c_del(c,f)   (c->Status = ((c->cursor)->c_del)(c->cursor,f))
3200
 
DualType
3201
 
cu_c_del(db, flags=0)
3202
 
    int                 flags
3203
 
    BerkeleyDB::Cursor  db
3204
 
        INIT:
3205
 
          CurrentDB = db->parent_db ;
3206
 
          ckActive_Cursor(db->active) ;
3207
 
        OUTPUT:
3208
 
          RETVAL
3209
 
 
3210
 
 
3211
 
#define cu_c_get(c,k,d,f) (c->Status = (c->cursor->c_get)(c->cursor,&k,&d,f))
3212
 
DualType
3213
 
cu_c_get(db, key, data, flags=0)
3214
 
    int                 flags
3215
 
    BerkeleyDB::Cursor  db
3216
 
    DBTKEY_B            key
3217
 
    DBT_B               data
3218
 
        INIT:
3219
 
          Trace(("c_get db [%p] in [%p] flags [%d]\n", db->dbp, db, flags)) ;
3220
 
          CurrentDB = db->parent_db ;
3221
 
          ckActive_Cursor(db->active) ;
3222
 
          SetPartial(data,db) ;
3223
 
          Trace(("c_get end\n")) ;
3224
 
        OUTPUT:
3225
 
          RETVAL
3226
 
          key
3227
 
          data          if (! flagSet(DB_JOIN_ITEM)) OutputValue_B(ST(2), data) ;
3228
 
 
3229
 
#define cu_c_pget(c,k,p,d,f) (c->Status = (c->secondary_db ? (c->cursor->c_pget)(c->cursor,&k,&p,&d,f) : EINVAL))
3230
 
DualType
3231
 
cu_c_pget(db, key, pkey, data, flags=0)
3232
 
    int                 flags
3233
 
    BerkeleyDB::Cursor  db
3234
 
    DBTKEY_B            key
3235
 
    DBTKEY_B            pkey = NO_INIT
3236
 
    DBT_B               data
3237
 
        CODE:
3238
 
#ifndef AT_LEAST_DB_3_3
3239
 
          softCrash("db_c_pget needs at least Berkeley DB 3.3");
3240
 
#else
3241
 
          Trace(("c_pget db [%d] flags [%d]\n", db, flags)) ;
3242
 
          CurrentDB = db->parent_db ;
3243
 
          ckActive_Cursor(db->active) ;
3244
 
          SetPartial(data,db) ;
3245
 
          DBT_clear(pkey);
3246
 
          RETVAL = cu_c_pget(db, key, pkey, data, flags);
3247
 
          Trace(("c_pget end\n")) ;
3248
 
#endif
3249
 
        OUTPUT:
3250
 
          RETVAL
3251
 
          key
3252
 
          pkey
3253
 
          data          if (! flagSet(DB_JOIN_ITEM)) OutputValue_B(ST(2), data) ;
3254
 
 
3255
 
 
3256
 
 
3257
 
#define cu_c_put(c,k,d,f)  (c->Status = (c->cursor->c_put)(c->cursor,&k,&d,f))
3258
 
DualType
3259
 
cu_c_put(db, key, data, flags=0)
3260
 
    int                 flags
3261
 
    BerkeleyDB::Cursor  db
3262
 
    DBTKEY              key
3263
 
    DBT                 data
3264
 
        INIT:
3265
 
          CurrentDB = db->parent_db ;
3266
 
          ckActive_Cursor(db->active) ;
3267
 
          /* SetPartial(data,db) ; */
3268
 
        OUTPUT:
3269
 
          RETVAL
3270
 
 
3271
 
#define cu_c_count(c,p,f) (c->Status = (c->cursor->c_count)(c->cursor,&p,f))
3272
 
DualType
3273
 
cu_c_count(db, count, flags=0)
3274
 
    int                 flags
3275
 
    BerkeleyDB::Cursor  db
3276
 
    u_int32_t           count = NO_INIT
3277
 
        CODE:
3278
 
#ifndef AT_LEAST_DB_3_1
3279
 
          softCrash("c_count needs at least Berkeley DB 3.1.x");
3280
 
#else
3281
 
          Trace(("c_get count [%d] flags [%d]\n", db, flags)) ;
3282
 
          CurrentDB = db->parent_db ;
3283
 
          ckActive_Cursor(db->active) ;
3284
 
          RETVAL = cu_c_count(db, count, flags) ;
3285
 
          Trace(("    c_count got %d duplicates\n", count)) ;
3286
 
#endif
3287
 
        OUTPUT:
3288
 
          RETVAL
3289
 
          count
3290
 
 
3291
 
MODULE = BerkeleyDB::TxnMgr           PACKAGE = BerkeleyDB::TxnMgr      PREFIX = xx_
3292
 
 
3293
 
BerkeleyDB::Txn::Raw
3294
 
_txn_begin(txnmgr, pid=NULL, flags=0)
3295
 
        u_int32_t               flags
3296
 
        BerkeleyDB::TxnMgr      txnmgr
3297
 
        BerkeleyDB::Txn         pid
3298
 
        CODE:
3299
 
        {
3300
 
            DB_TXN *txn ;
3301
 
            DB_TXN *p_id = NULL ;
3302
 
#if DB_VERSION_MAJOR == 2
3303
 
            if (txnmgr->env->Env->tx_info == NULL)
3304
 
                softCrash("Transaction Manager not enabled") ;
3305
 
#endif
3306
 
            if (pid)
3307
 
                p_id = pid->txn ;
3308
 
            txnmgr->env->TxnMgrStatus =
3309
 
#if DB_VERSION_MAJOR == 2
3310
 
                txn_begin(txnmgr->env->Env->tx_info, p_id, &txn) ;
3311
 
#else
3312
 
#  ifdef AT_LEAST_DB_4
3313
 
                txnmgr->env->Env->txn_begin(txnmgr->env->Env, p_id, &txn, flags) ;
3314
 
#  else
3315
 
                txn_begin(txnmgr->env->Env, p_id, &txn, flags) ;
3316
 
#  endif
3317
 
#endif
3318
 
            if (txnmgr->env->TxnMgrStatus == 0) {
3319
 
              ZMALLOC(RETVAL, BerkeleyDB_Txn_type) ;
3320
 
              RETVAL->txn  = txn ;
3321
 
              RETVAL->active = TRUE ;
3322
 
              Trace(("_txn_begin created txn [%d] in [%d]\n", txn, RETVAL));
3323
 
              hash_store_iv("BerkeleyDB::Term::Txn", (char *)RETVAL, 1) ;
3324
 
            }
3325
 
            else
3326
 
                RETVAL = NULL ;
3327
 
        }
3328
 
        OUTPUT:
3329
 
            RETVAL
3330
 
 
3331
 
 
3332
 
DualType
3333
 
status(mgr)
3334
 
        BerkeleyDB::TxnMgr      mgr
3335
 
        CODE:
3336
 
            RETVAL =  mgr->env->TxnMgrStatus ;
3337
 
        OUTPUT:
3338
 
            RETVAL
3339
 
 
3340
 
 
3341
 
void
3342
 
_DESTROY(mgr)
3343
 
    BerkeleyDB::TxnMgr  mgr
3344
 
        CODE:
3345
 
          Trace(("In BerkeleyDB::TxnMgr::DESTROY dirty=%d\n", PL_dirty)) ;
3346
 
          Safefree(mgr) ;
3347
 
          Trace(("End of BerkeleyDB::TxnMgr::DESTROY\n")) ;
3348
 
 
3349
 
DualType
3350
 
txn_close(txnp)
3351
 
        BerkeleyDB::TxnMgr      txnp
3352
 
        NOT_IMPLEMENTED_YET
3353
 
 
3354
 
 
3355
 
#if DB_VERSION_MAJOR == 2
3356
 
#  define xx_txn_checkpoint(t,k,m,f) txn_checkpoint(t->env->Env->tx_info, k, m)
3357
 
#else
3358
 
#  ifdef AT_LEAST_DB_4 
3359
 
#    define xx_txn_checkpoint(e,k,m,f) e->env->Env->txn_checkpoint(e->env->Env, k, m, f)
3360
 
#  else
3361
 
#    ifdef AT_LEAST_DB_3_1
3362
 
#      define xx_txn_checkpoint(t,k,m,f) txn_checkpoint(t->env->Env, k, m, 0)
3363
 
#    else
3364
 
#      define xx_txn_checkpoint(t,k,m,f) txn_checkpoint(t->env->Env, k, m)
3365
 
#    endif
3366
 
#  endif
3367
 
#endif
3368
 
DualType
3369
 
xx_txn_checkpoint(txnp, kbyte, min, flags=0)
3370
 
        BerkeleyDB::TxnMgr      txnp
3371
 
        long                    kbyte
3372
 
        long                    min
3373
 
        u_int32_t               flags
3374
 
 
3375
 
HV *
3376
 
txn_stat(txnp)
3377
 
        BerkeleyDB::TxnMgr      txnp
3378
 
        HV *                    RETVAL = NULL ;
3379
 
        CODE:
3380
 
        {
3381
 
            DB_TXN_STAT *       stat ;
3382
 
#ifdef AT_LEAST_DB_4
3383
 
            if(txnp->env->Env->txn_stat(txnp->env->Env, &stat, 0) == 0) {
3384
 
#else
3385
 
#  ifdef AT_LEAST_DB_3_3
3386
 
            if(txn_stat(txnp->env->Env, &stat) == 0) {
3387
 
#  else
3388
 
#    if DB_VERSION_MAJOR == 2
3389
 
            if(txn_stat(txnp->env->Env->tx_info, &stat, safemalloc) == 0) {
3390
 
#    else
3391
 
            if(txn_stat(txnp->env->Env, &stat, safemalloc) == 0) {
3392
 
#    endif
3393
 
#  endif
3394
 
#endif
3395
 
                RETVAL = (HV*)sv_2mortal((SV*)newHV()) ;
3396
 
                hv_store_iv(RETVAL, "st_time_ckp", stat->st_time_ckp) ;
3397
 
                hv_store_iv(RETVAL, "st_last_txnid", stat->st_last_txnid) ;
3398
 
                hv_store_iv(RETVAL, "st_maxtxns", stat->st_maxtxns) ;
3399
 
                hv_store_iv(RETVAL, "st_naborts", stat->st_naborts) ;
3400
 
                hv_store_iv(RETVAL, "st_nbegins", stat->st_nbegins) ;
3401
 
                hv_store_iv(RETVAL, "st_ncommits", stat->st_ncommits) ;
3402
 
                hv_store_iv(RETVAL, "st_nactive", stat->st_nactive) ;
3403
 
#if DB_VERSION_MAJOR > 2
3404
 
                hv_store_iv(RETVAL, "st_maxnactive", stat->st_maxnactive) ;
3405
 
                hv_store_iv(RETVAL, "st_regsize", stat->st_regsize) ;
3406
 
                hv_store_iv(RETVAL, "st_region_wait", stat->st_region_wait) ;
3407
 
                hv_store_iv(RETVAL, "st_region_nowait", stat->st_region_nowait) ;
3408
 
#endif
3409
 
                safefree(stat) ;
3410
 
            }
3411
 
        }
3412
 
        OUTPUT:
3413
 
            RETVAL
3414
 
 
3415
 
 
3416
 
BerkeleyDB::TxnMgr
3417
 
txn_open(dir, flags, mode, dbenv)
3418
 
    int                 flags
3419
 
    const char *        dir
3420
 
    int                 mode
3421
 
    BerkeleyDB::Env     dbenv
3422
 
        NOT_IMPLEMENTED_YET
3423
 
 
3424
 
 
3425
 
MODULE = BerkeleyDB::Txn              PACKAGE = BerkeleyDB::Txn         PREFIX = xx_
3426
 
 
3427
 
DualType
3428
 
status(tid)
3429
 
        BerkeleyDB::Txn         tid
3430
 
        CODE:
3431
 
            RETVAL =  tid->Status ;
3432
 
        OUTPUT:
3433
 
            RETVAL
3434
 
 
3435
 
int
3436
 
_DESTROY(tid)
3437
 
    BerkeleyDB::Txn     tid
3438
 
        CODE:
3439
 
          Trace(("In BerkeleyDB::Txn::_DESTROY txn [%d] active [%d] dirty=%d\n", tid->txn, tid->active, PL_dirty)) ;
3440
 
          if (tid->active)
3441
 
#ifdef AT_LEAST_DB_4
3442
 
            tid->txn->abort(tid->txn) ;
3443
 
#else
3444
 
            txn_abort(tid->txn) ;
3445
 
#endif
3446
 
          RETVAL = (int)tid ;
3447
 
          hash_delete("BerkeleyDB::Term::Txn", (char *)tid) ;
3448
 
          Safefree(tid) ;
3449
 
          Trace(("End of BerkeleyDB::Txn::DESTROY\n")) ;
3450
 
        OUTPUT:
3451
 
          RETVAL
3452
 
 
3453
 
#define xx_txn_unlink(d,f,e)    txn_unlink(d,f,&(e->Env))
3454
 
DualType
3455
 
xx_txn_unlink(dir, force, dbenv)
3456
 
    const char *        dir
3457
 
    int                 force
3458
 
    BerkeleyDB::Env     dbenv
3459
 
        NOT_IMPLEMENTED_YET
3460
 
 
3461
 
#ifdef AT_LEAST_DB_4
3462
 
#  define xx_txn_prepare(t) (t->Status = t->txn->prepare(t->txn, 0))
3463
 
#else
3464
 
#  ifdef AT_LEAST_DB_3_3
3465
 
#    define xx_txn_prepare(t) (t->Status = txn_prepare(t->txn, 0))
3466
 
#  else
3467
 
#    define xx_txn_prepare(t) (t->Status = txn_prepare(t->txn))
3468
 
#  endif
3469
 
#endif
3470
 
DualType
3471
 
xx_txn_prepare(tid)
3472
 
        BerkeleyDB::Txn tid
3473
 
        INIT:
3474
 
            ckActive_Transaction(tid->active) ;
3475
 
 
3476
 
#ifdef AT_LEAST_DB_4
3477
 
#  define _txn_commit(t,flags) (t->Status = t->txn->commit(t->txn, flags))
3478
 
#else
3479
 
#  if DB_VERSION_MAJOR == 2
3480
 
#    define _txn_commit(t,flags) (t->Status = txn_commit(t->txn))
3481
 
#  else
3482
 
#    define _txn_commit(t, flags) (t->Status = txn_commit(t->txn, flags))
3483
 
#  endif
3484
 
#endif
3485
 
DualType
3486
 
_txn_commit(tid, flags=0)
3487
 
        u_int32_t       flags
3488
 
        BerkeleyDB::Txn tid
3489
 
        INIT:
3490
 
            ckActive_Transaction(tid->active) ;
3491
 
            hash_delete("BerkeleyDB::Term::Txn", (char *)tid) ;
3492
 
            tid->active = FALSE ;
3493
 
 
3494
 
#ifdef AT_LEAST_DB_4
3495
 
#  define _txn_abort(t) (t->Status = t->txn->abort(t->txn))
3496
 
#else
3497
 
#  define _txn_abort(t) (t->Status = txn_abort(t->txn))
3498
 
#endif
3499
 
DualType
3500
 
_txn_abort(tid)
3501
 
        BerkeleyDB::Txn tid
3502
 
        INIT:
3503
 
            ckActive_Transaction(tid->active) ;
3504
 
            hash_delete("BerkeleyDB::Term::Txn", (char *)tid) ;
3505
 
            tid->active = FALSE ;
3506
 
 
3507
 
#ifdef AT_LEAST_DB_4
3508
 
#  define _txn_discard(t,f) (t->Status = t->txn->discard(t->txn, f))
3509
 
#else
3510
 
#  ifdef AT_LEAST_DB_3_3_4
3511
 
#    define _txn_discard(t,f) (t->Status = txn_discard(t->txn, f))
3512
 
#  else
3513
 
#    define _txn_discard(t,f) (int)softCrash("txn_discard needs Berkeley DB 3.3.4 or better") ;
3514
 
#  endif
3515
 
#endif
3516
 
DualType
3517
 
_txn_discard(tid, flags=0)
3518
 
        BerkeleyDB::Txn tid
3519
 
        u_int32_t       flags
3520
 
        INIT:
3521
 
            ckActive_Transaction(tid->active) ;
3522
 
            hash_delete("BerkeleyDB::Term::Txn", (char *)tid) ;
3523
 
            tid->active = FALSE ;
3524
 
 
3525
 
#ifdef AT_LEAST_DB_4
3526
 
#  define xx_txn_id(t) t->txn->id(t->txn)
3527
 
#else
3528
 
#  define xx_txn_id(t) txn_id(t->txn)
3529
 
#endif
3530
 
u_int32_t
3531
 
xx_txn_id(tid)
3532
 
        BerkeleyDB::Txn tid
3533
 
 
3534
 
MODULE = BerkeleyDB::_tiedHash        PACKAGE = BerkeleyDB::_tiedHash
3535
 
 
3536
 
int
3537
 
FIRSTKEY(db)
3538
 
        BerkeleyDB::Common         db
3539
 
        CODE:
3540
 
        {
3541
 
            DBTKEY      key ;
3542
 
            DBT         value ;
3543
 
            DBC *       cursor ;
3544
 
 
3545
 
            /*
3546
 
                TODO!
3547
 
                set partial value to 0 - to eliminate the retrieval of
3548
 
                the value need to store any existing partial settings &
3549
 
                restore at the end.
3550
 
 
3551
 
             */
3552
 
            CurrentDB = db ;
3553
 
            DBT_clear(key) ;
3554
 
            DBT_clear(value) ;
3555
 
            /* If necessary create a cursor for FIRSTKEY/NEXTKEY use */
3556
 
            if (!db->cursor &&
3557
 
                (db->Status = db_cursor(db, db->txn, &cursor, 0)) == 0 )
3558
 
                    db->cursor  = cursor ;
3559
 
 
3560
 
            if (db->cursor)
3561
 
                RETVAL = (db->Status) =
3562
 
                    ((db->cursor)->c_get)(db->cursor, &key, &value, DB_FIRST);
3563
 
            else
3564
 
                RETVAL = db->Status ;
3565
 
            /* check for end of cursor */
3566
 
            if (RETVAL == DB_NOTFOUND) {
3567
 
              ((db->cursor)->c_close)(db->cursor) ;
3568
 
              db->cursor = NULL ;
3569
 
            }
3570
 
            ST(0) = sv_newmortal();
3571
 
            OutputKey(ST(0), key)
3572
 
        }
3573
 
 
3574
 
 
3575
 
 
3576
 
int
3577
 
NEXTKEY(db, key)
3578
 
        BerkeleyDB::Common  db
3579
 
        DBTKEY              key = NO_INIT
3580
 
        CODE:
3581
 
        {
3582
 
            DBT         value ;
3583
 
 
3584
 
            CurrentDB = db ;
3585
 
            DBT_clear(key) ;
3586
 
            DBT_clear(value) ;
3587
 
            key.flags = 0 ;
3588
 
            RETVAL = (db->Status) =
3589
 
                ((db->cursor)->c_get)(db->cursor, &key, &value, DB_NEXT);
3590
 
 
3591
 
            /* check for end of cursor */
3592
 
            if (RETVAL == DB_NOTFOUND) {
3593
 
              ((db->cursor)->c_close)(db->cursor) ;
3594
 
              db->cursor = NULL ;
3595
 
            }
3596
 
            ST(0) = sv_newmortal();
3597
 
            OutputKey(ST(0), key)
3598
 
        }
3599
 
 
3600
 
MODULE = BerkeleyDB::_tiedArray        PACKAGE = BerkeleyDB::_tiedArray
3601
 
 
3602
 
I32
3603
 
FETCHSIZE(db)
3604
 
        BerkeleyDB::Common         db
3605
 
        CODE:
3606
 
            CurrentDB = db ;
3607
 
            RETVAL = GetArrayLength(db) ;
3608
 
        OUTPUT:
3609
 
            RETVAL
3610
 
 
3611
 
 
3612
 
MODULE = BerkeleyDB        PACKAGE = BerkeleyDB
3613
 
 
3614
 
BOOT:
3615
 
  {
3616
 
    SV * sv_err = perl_get_sv(ERR_BUFF, GV_ADD|GV_ADDMULTI) ;
3617
 
    SV * version_sv = perl_get_sv("BerkeleyDB::db_version", GV_ADD|GV_ADDMULTI) ;
3618
 
    SV * ver_sv = perl_get_sv("BerkeleyDB::db_ver", GV_ADD|GV_ADDMULTI) ;
3619
 
    int Major, Minor, Patch ;
3620
 
    (void)db_version(&Major, &Minor, &Patch) ;
3621
 
    /* Check that the versions of db.h and libdb.a are the same */
3622
 
    if (Major != DB_VERSION_MAJOR || Minor != DB_VERSION_MINOR
3623
 
                || Patch != DB_VERSION_PATCH)
3624
 
        croak("\nBerkeleyDB needs compatible versions of libdb & db.h\n\tyou have db.h version %d.%d.%d and libdb version %d.%d.%d\n",
3625
 
                DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH,
3626
 
                Major, Minor, Patch) ;
3627
 
 
3628
 
    if (Major < 2 || (Major == 2 && Minor < 6))
3629
 
    {
3630
 
        croak("BerkeleyDB needs Berkeley DB 2.6 or greater. This is %d.%d.%d\n",
3631
 
                Major, Minor, Patch) ;
3632
 
    }
3633
 
    sv_setpvf(version_sv, "%d.%d", Major, Minor) ;
3634
 
    sv_setpvf(ver_sv, "%d.%03d%03d", Major, Minor, Patch) ;
3635
 
    sv_setpv(sv_err, "");
3636
 
 
3637
 
    DBT_clear(empty) ;
3638
 
    empty.data  = &zero ;
3639
 
    empty.size  =  sizeof(db_recno_t) ;
3640
 
    empty.flags = 0 ;
3641
 
 
3642
 
  }
3643