3
BerkeleyDB.xs -- Perl 5 interface to Berkeley DB version 2 & 3
5
written by Paul Marquess <Paul.Marquess@btinternet.com>
7
All comments/suggestions/problems are welcome
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.
13
Please refer to the COPYRIGHT section in
16
0.01 - First Alpha Release
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) */
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. */
57
# define GetFILEptr(sv) PerlIO_findFILE(IoOFP(sv_2io(sv)))
59
# define GetFILEptr(sv) IoOFP(sv_2io(sv))
64
/* Check the version of Berkeley DB */
66
#ifndef DB_VERSION_MAJOR
68
#error db.h is from Berkeley DB 1.x - need at least Berkeley DB 2.6.4
70
#error db.h is not for Berkeley DB at all.
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
80
#if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0)
84
#if DB_VERSION_MAJOR >= 3
85
# define AT_LEAST_DB_3
88
#if DB_VERSION_MAJOR > 3 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 1)
89
# define AT_LEAST_DB_3_1
92
#if DB_VERSION_MAJOR > 3 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 2)
93
# define AT_LEAST_DB_3_2
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
102
#if DB_VERSION_MAJOR > 3 || (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 3)
103
# define AT_LEAST_DB_3_3
106
#if DB_VERSION_MAJOR >= 4
107
# define AT_LEAST_DB_4
110
#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
111
# define AT_LEAST_DB_4_1
118
#define DBM_FILTERING
120
/* #define ALLOW_RECNO_OFFSET */
123
#if DB_VERSION_MAJOR == 2 && ! defined(DB_LOCK_DEADLOCK)
124
# define DB_LOCK_DEADLOCK EAGAIN
125
#endif /* DB_VERSION_MAJOR == 2 */
127
#if DB_VERSION_MAJOR == 2
129
#endif /* DB_VERSION_MAJOR == 2 */
131
#ifdef AT_LEAST_DB_3_2
132
# define DB_callback DB * db,
137
#if DB_VERSION_MAJOR > 2
144
void *(*db_malloc) __P((size_t));
146
__P((DB_callback const DBT *, const DBT *));
151
__P((DB_callback const DBT *, const DBT *));
153
__P((DB_callback const DBT *, const DBT *));
158
__P((DB_callback const void *, u_int32_t));
165
#define DB_DELIMITER 0x0001
166
#define DB_FIXEDLEN 0x0008
167
#define DB_PAD 0x0010
169
u_int32_t q_extentsize;
172
#endif /* DB_VERSION_MAJOR > 2 */
176
/* char ErrBuff[1000] ; */
184
} BerkeleyDB_ENV_type ;
189
bool recno_or_queue ;
191
BerkeleyDB_ENV_type * parent_env ;
196
bool in_dup_compare ;
201
#ifdef AT_LEAST_DB_3_3
214
#ifdef ALLOW_RECNO_OFFSET
218
SV * filter_fetch_key ;
219
SV * filter_store_key ;
220
SV * filter_fetch_value ;
221
SV * filter_store_value ;
229
bool recno_or_queue ;
236
#ifdef AT_LEAST_DB_3_3
244
BerkeleyDB_type * parent_db ;
249
#ifdef ALLOW_RECNO_OFFSET
253
SV * filter_fetch_key ;
254
SV * filter_store_key ;
255
SV * filter_fetch_value ;
256
SV * filter_store_value ;
259
} BerkeleyDB_Cursor_type;
262
BerkeleyDB_ENV_type * env ;
263
} BerkeleyDB_TxnMgr_type ;
270
} BerkeleyDB_Txn_type ;
272
typedef DB_TXN BerkeleyDB_Txn_type ;
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 ;
301
typedef DB_LOG * BerkeleyDB__Log ;
302
typedef DB_LOCKTAB * BerkeleyDB__Lock ;
305
typedef DBT DBT_OPT ;
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 ;
314
hash_delete(char * hash, char * key);
317
# define Trace(x) printf x
322
#ifdef ALLOW_RECNO_OFFSET
323
# define RECNO_BASE db->array_base
325
# define RECNO_BASE 1
328
#if DB_VERSION_MAJOR == 2
329
# define flagSet_DB2(i, f) i |= f
331
# define flagSet_DB2(i, f)
334
#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
335
# define flagSet(bitmask) (flags & (bitmask))
337
# define flagSet(bitmask) ((flags & DB_OPFLAGS_MASK) == (bitmask))
340
#if DB_VERSION_MAJOR == 2
341
# define BackRef internal
343
# if DB_VERSION_MAJOR == 3 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 0)
344
# define BackRef cj_internal
346
# define BackRef api_internal
350
#define ERR_BUFF "BerkeleyDB::Error"
352
#define ZMALLOC(to, typ) ((to = (typ *)safemalloc(sizeof(typ))), \
355
#define DBT_clear(x) Zero(&x, 1, DBT) ;
358
#define getInnerObject(x) (*av_fetch((AV*)SvRV(x), 0, FALSE))
360
#define getInnerObject(x) ((SV*)SvRV(sv))
363
#define my_sv_setpvn(sv, d, s) (s ? sv_setpvn(sv, d, s) : sv_setpv(sv, "") )
365
#define SetValue_iv(i, k) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) \
367
#define SetValue_io(i, k) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) \
369
#define SetValue_sv(i, k) if ((sv = readHash(hash, k)) && sv != &PL_sv_undef) \
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) \
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) ; \
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) ; \
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) ; \
392
#define LastDBerror DB_RUNRECOVERY
394
#define setDUALerrno(var, err) \
395
sv_setnv(var, (double)err) ; \
396
sv_setpv(var, ((err) ? db_strerror(err) : "")) ;\
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") ; \
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); \
413
my_sv_setpvn(arg, name.data, name.size) ; \
415
DBM_ckFilter(arg, filter_fetch_value, "filter_fetch_value"); \
419
#define OutputKey(arg, name) \
422
if (!db->recno_or_queue) { \
423
my_sv_setpvn(arg, name.data, name.size); \
426
sv_setiv(arg, (I32)*(I32*)name.data - RECNO_BASE); \
427
DBM_ckFilter(arg, filter_fetch_key, "filter_fetch_key") ; \
431
#define OutputKey_B(arg, name) \
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); \
440
my_sv_setpvn(arg, name.data, name.size); \
442
DBM_ckFilter(arg, filter_fetch_key, "filter_fetch_key") ; \
446
#define SetPartial(data,db) \
447
data.flags = db->partial ; \
448
data.dlen = db->dlen ; \
449
data.doff = db->doff ;
451
#define ckActive(active, type) \
454
softCrash("%s is already closed", type) ; \
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")
463
/* Internal Global Data */
464
static db_recno_t Value ;
465
static db_recno_t zero = 0 ;
466
static BerkeleyDB CurrentDB ;
468
static DBTKEY empty ;
470
static char ErrBuff[1000] ;
473
#ifdef AT_LEAST_DB_3_3
474
# if PERL_REVISION == 5 && PERL_VERSION <= 4
476
/* saferealloc in perl5.004 will croak if it is given a NULL pointer*/
478
MyRealloc(void * ptr, size_t size)
481
return safemalloc(size) ;
483
return saferealloc(ptr, size) ;
487
# define MyRealloc saferealloc
492
my_strdup(const char *s)
498
MEM_SIZE l = strlen(s);
499
char *s1 = (char *)safemalloc(l);
501
Copy(s, s1, (MEM_SIZE)l, char);
506
#if DB_VERSION_MAJOR == 2
514
return Strerror(err) ;
518
return ("DB_INCOMPLETE: Sync was unable to complete");
520
return ("DB_KEYEMPTY: Non-existent key/data pair");
522
return ("DB_KEYEXIST: Key/data pair already exists");
523
case DB_LOCK_DEADLOCK:
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");
531
return ("DB_NOTFOUND: No matching key/data pair found");
533
return ("DB_RUNRECOVERY: Fatal error, run database recovery");
535
return "Unknown Error" ;
539
#endif /* DB_VERSION_MAJOR == 2 */
542
#if DB_VERSION_MAJOR > 2
544
my_db_strerror(int err)
546
static char buffer[1000] ;
547
SV * sv = perl_get_sv(ERR_BUFF, FALSE) ;
548
sprintf(buffer, "%d: %s", err, db_strerror(err)) ;
550
strcat(buffer, ", ") ;
551
strcat(buffer, SvPVX(sv)) ;
559
close_everything(void)
562
Trace(("close_everything\n")) ;
563
/* Abort All Transactions */
565
BerkeleyDB__Txn__Raw tid ;
568
HV * hv = perl_get_hv("BerkeleyDB::Term::Txn", TRUE);
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));
578
tid->txn->abort(tid->txn) ;
584
tid->active = FALSE ;
587
Trace(("End of BerkeleyDB::Term::close_all_txns aborted %d of %d transactios\n",closed, all)) ;
590
/* Close All Cursors */
592
BerkeleyDB__Cursor db ;
595
HV * hv = perl_get_hv("BerkeleyDB::Term::Cursor", TRUE);
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));
604
((db->cursor)->c_close)(db->cursor) ;
610
Trace(("End of BerkeleyDB::Term::close_all_cursors closed %d of %d cursors\n",closed, all)) ;
613
/* Close All Databases */
618
HV * hv = perl_get_hv("BerkeleyDB::Term::Db", TRUE);
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));
627
(db->dbp->close)(db->dbp, 0) ;
633
Trace(("End of BerkeleyDB::Term::close_all_dbs closed %d of %d dbs\n",closed, all)) ;
636
/* Close All Environments */
638
BerkeleyDB__Env env ;
641
HV * hv = perl_get_hv("BerkeleyDB::Term::Env", TRUE);
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));
650
#if DB_VERSION_MAJOR == 2
651
db_appexit(env->Env) ;
653
(env->Env->close)(env->Env, 0) ;
657
env->active = FALSE ;
660
Trace(("End of BerkeleyDB::Term::close_all_envs closed %d of %d dbs\n",closed, all)) ;
663
Trace(("end close_everything\n")) ;
668
destroyDB(BerkeleyDB db)
671
if (! PL_dirty && db->active) {
672
-- db->open_cursors ;
673
((db->dbp)->close)(db->dbp, 0) ;
676
SvREFCNT_dec(db->hash) ;
678
SvREFCNT_dec(db->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) ;
686
SvREFCNT_dec(db->prefix) ;
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) ;
697
hash_delete("BerkeleyDB::Term::Db", (char *)db) ;
699
Safefree(db->filename) ;
704
softCrash(const char *pat, ...)
711
Trace(("softCrash: %s\n", pat)) ;
713
#define ABORT_PREFIX "BerkeleyDB Aborting: "
715
/* buffer = (char*) safemalloc(strlen(pat) + strlen(ABORT_PREFIX) + 1) ; */
716
strcpy(buffer1, ABORT_PREFIX) ;
717
strcat(buffer1, pat) ;
719
vsprintf(buffer2, buffer1, args) ;
730
GetArrayLength(BerkeleyDB db)
739
#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
740
if ( ((db->dbp)->cursor)(db->dbp, db->txn, &cursor) == 0 )
742
if ( ((db->dbp)->cursor)(db->dbp, db->txn, &cursor, 0) == 0 )
745
RETVAL = cursor->c_get(cursor, &key, &value, DB_LAST) ;
747
RETVAL = *(I32 *)key.data ;
748
else /* No key means empty file */
750
cursor->c_close(cursor) ;
753
Trace(("GetArrayLength got %d\n", RETVAL)) ;
754
return ((I32)RETVAL) ;
759
#define GetRecnoKey(db, value) _GetRecnoKey(db, value)
762
_GetRecnoKey(BerkeleyDB db, I32 value)
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) ;
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) ;
773
value = length + value + RECNO_BASE ;
778
Trace(("GetRecnoKey end value = %d\n", value)) ;
786
#ifdef ALLOW_RECNO_OFFSET
787
#define GetRecnoKey(db, value) _GetRecnoKey(db, value)
790
_GetRecnoKey(BerkeleyDB db, I32 value)
792
if (value + RECNO_BASE < 1)
793
softCrash("key value %d < base (%d)", (value), RECNO_BASE?0:1) ;
794
return value + RECNO_BASE ;
798
#endif /* ALLOW_RECNO_OFFSET */
801
#define GetRecnoKey(db, value) ((value) + RECNO_BASE )
807
GetInternalObject(SV * sv)
809
SV * info = (SV*) NULL ;
813
Trace(("in GetInternalObject %d\n", sv)) ;
814
if (sv == NULL || !SvROK(sv))
820
if (SvTYPE(s) == SVt_PVHV || SvTYPE(s) == SVt_PVAV)
821
mg = mg_find(s, 'P') ;
823
mg = mg_find(s, 'q') ;
825
/* all this testing is probably overkill, but till I know more
826
about global destruction it stays.
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) ;
835
Trace(("end of GetInternalObject %d\n", info)) ;
841
btree_compare(DB_callback const DBT * key1, const DBT * key2 )
844
char * data1, * data2 ;
847
BerkeleyDB keepDB = CurrentDB ;
849
data1 = (char*) key1->data ;
850
data2 = (char*) key2->data ;
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
868
PUSHs(sv_2mortal(newSVpvn(data1,key1->size)));
869
PUSHs(sv_2mortal(newSVpvn(data2,key2->size)));
872
count = perl_call_sv(CurrentDB->compare, G_SCALAR);
877
softCrash ("in btree_compare - expected 1 return value from compare sub, got %d", count) ;
890
dup_compare(DB_callback const DBT * key1, const DBT * key2 )
893
char * data1, * data2 ;
896
BerkeleyDB keepDB = CurrentDB ;
898
Trace(("In dup_compare \n")) ;
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) ;
904
data1 = (char*) key1->data ;
905
data2 = (char*) key2->data ;
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
923
PUSHs(sv_2mortal(newSVpvn(data1,key1->size)));
924
PUSHs(sv_2mortal(newSVpvn(data2,key2->size)));
927
count = perl_call_sv(CurrentDB->dup_compare, G_SCALAR);
932
softCrash ("dup_compare: expected 1 return value from compare sub, got %d", count) ;
945
btree_prefix(DB_callback const DBT * key1, const DBT * key2 )
948
char * data1, * data2 ;
951
BerkeleyDB keepDB = CurrentDB ;
953
data1 = (char*) key1->data ;
954
data2 = (char*) key2->data ;
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
972
PUSHs(sv_2mortal(newSVpvn(data1,key1->size)));
973
PUSHs(sv_2mortal(newSVpvn(data2,key2->size)));
976
count = perl_call_sv(CurrentDB->prefix, G_SCALAR);
981
softCrash ("btree_prefix: expected 1 return value from prefix sub, got %d", count) ;
994
hash_cb(DB_callback const void * data, u_int32_t size)
999
BerkeleyDB keepDB = CurrentDB ;
1011
XPUSHs(sv_2mortal(newSVpvn((char*)data,size)));
1014
count = perl_call_sv(CurrentDB->hash, G_SCALAR);
1019
softCrash ("hash_cb: expected 1 return value from hash sub, got %d", count) ;
1026
CurrentDB = keepDB ;
1031
#ifdef AT_LEAST_DB_3_3
1034
associate_cb(DB_callback const DBT * pkey, const DBT * pdata, DBT * skey)
1037
char * pk_dat, * pd_dat, *sk_dat ;
1042
Trace(("In associate_cb \n")) ;
1043
if (((BerkeleyDB)db->BackRef)->associated == NULL){
1044
Trace(("No Callback registered\n")) ;
1048
skey_SV = newSVpv("",0);
1051
pk_dat = (char*) pkey->data ;
1052
pd_dat = (char*) pdata->data ;
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
1059
if (pkey->size == 0)
1061
if (pdata->size == 0)
1070
PUSHs(sv_2mortal(newSVpvn(pk_dat,pkey->size)));
1071
PUSHs(sv_2mortal(newSVpvn(pd_dat,pdata->size)));
1072
PUSHs(sv_2mortal(skey_SV));
1075
Trace(("calling associated cb\n"));
1076
count = perl_call_sv(((BerkeleyDB)db->BackRef)->associated, G_SCALAR);
1077
Trace(("called associated cb\n"));
1082
softCrash ("associate: expected 1 return value from prefix sub, got %d", count) ;
1088
/* retrieve the secondary key */
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));
1102
#endif /* AT_LEAST_DB_3_3 */
1105
db_errcall_cb(const char * db_errpfx, char * buffer)
1109
if (db_errpfx == NULL)
1111
if (buffer == NULL )
1114
if (strlen(db_errpfx) + strlen(buffer) + 3 <= 1000) {
1115
if (*db_errpfx != '\0') {
1116
strcat(ErrBuff, db_errpfx) ;
1117
strcat(ErrBuff, ": ") ;
1119
strcat(ErrBuff, buffer) ;
1124
SV * sv = perl_get_sv(ERR_BUFF, FALSE) ;
1127
sv_setpvf(sv, "%s: %s", db_errpfx, buffer) ;
1129
sv_setpv(sv, buffer) ;
1134
readHash(HV * hash, char * key)
1137
svp = hv_fetch(hash, key, strlen(key), FALSE);
1138
if (svp && SvOK(*svp))
1144
hash_delete(char * hash, char * key)
1146
HV * hv = perl_get_hv(hash, TRUE);
1147
(void) hv_delete(hv, (char*)&key, sizeof(key), G_DISCARD);
1151
hash_store_iv(char * hash, char * key, IV value)
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) ; */
1159
hv_store_iv(HV * hash, char * key, IV value)
1161
hv_store(hash, key, strlen(key), newSViv(value), 0);
1169
BerkeleyDB__Env dbenv ,
1170
BerkeleyDB__Txn txn,
1172
const char * subname,
1179
DB_ENV * env = NULL ;
1180
BerkeleyDB RETVAL = NULL ;
1183
DB_TXN* txnid = NULL ;
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)) ;
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)) ;
1198
#if DB_VERSION_MAJOR == 2
1200
softCrash("Subname needs Berkeley DB 3 or better") ;
1203
#if DB_VERSION_MAJOR > 2
1204
Status = db_create(&dbp, env, 0) ;
1205
Trace(("db_create returned %s\n", my_db_strerror(Status))) ;
1209
#ifdef AT_LEAST_DB_3_3
1211
dbp->set_alloc(dbp, safemalloc, MyRealloc, safefree) ;
1212
dbp->set_errcall(dbp, db_errcall_cb) ;
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
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)));
1329
Status = dbp->set_flags(dbp, info->flags) ;
1330
Trace(("set_flags [%d] returned %s\n",
1331
info->flags, my_db_strerror(Status)));
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)));
1344
softCrash("-ExtentSize needs at least Berkeley DB 3.2.x") ;
1348
#ifdef AT_LEAST_DB_4_1
1349
if ((Status = (dbp->open)(dbp, txnid, file, subname, type, flags, mode)) == 0) {
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 */
1357
Trace(("db_opened ok\n"));
1358
#ifdef AT_LEAST_DB_3_3
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) ;
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)) ;
1381
RETVAL->parent_env = dbenv ;
1382
dbenv->Status = Status ;
1383
++ dbenv->open_dbs ;
1387
#if DB_VERSION_MAJOR > 2
1388
(dbp->close)(dbp, 0) ;
1391
Trace(("db open returned %s\n", my_db_strerror(Status))) ;
1398
#include "constants.h"
1400
MODULE = BerkeleyDB PACKAGE = BerkeleyDB PREFIX = env_
1402
INCLUDE: constants.xs
1404
#define env_db_version(maj, min, patch) db_version(&maj, &min, &patch)
1406
env_db_version(maj, min, patch)
1417
db_value_set(value, which)
1428
#if DB_VERSION_MAJOR == 2
1429
softCrash("BerkeleyDB::db_remove needs Berkeley DB 3.x or better") ;
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 ;
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) ;
1447
RETVAL = db_create(&dbp, dbenv, 0) ;
1449
RETVAL = dbp->remove(dbp, db, subdb, flags) ;
1461
#ifndef AT_LEAST_DB_3_1
1462
softCrash("BerkeleyDB::db_verify needs Berkeley DB 3.1.x or better") ;
1467
const char * db = NULL ;
1468
const char * subdb = NULL ;
1469
const char * outfile = NULL ;
1471
BerkeleyDB__Env env = NULL ;
1472
DB_ENV * dbenv = NULL ;
1473
u_int32_t flags = 0 ;
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) ;
1483
ofh = fopen(outfile, "w");
1490
RETVAL = db_create(&dbp, dbenv, 0) ;
1492
RETVAL = dbp->verify(dbp, db, subdb, ofh, flags) ;
1507
#ifndef AT_LEAST_DB_3_1
1508
softCrash("BerkeleyDB::db_rename needs Berkeley DB 3.1.x or better") ;
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 ;
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) ;
1528
RETVAL = db_create(&dbp, dbenv, 0) ;
1530
RETVAL = dbp->rename(dbp, db, subdb, newname, flags) ;
1537
MODULE = BerkeleyDB::Env PACKAGE = BerkeleyDB::Env PREFIX = env_
1540
BerkeleyDB::Env::Raw
1541
_db_appinit(self, ref)
1548
char * home = NULL ;
1549
char * errfile = NULL ;
1550
char * server = NULL ;
1551
char ** config = NULL ;
1556
SV * errprefix = NULL;
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
1572
softCrash("-SetFlags needs Berkeley DB 3.x or better") ;
1573
#endif /* ! AT_LEAST_DB_3 */
1574
#ifndef AT_LEAST_DB_3_1
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)) ;
1583
for (i = 0 ; i < 10 ; ++ i) {
1584
if (config[i] == NULL) {
1588
printf(" config = [%s]\n", config[i]) ;
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) ;
1599
/* Take a copy of the error prefix */
1601
Trace(("copying errprefix\n" )) ;
1602
RETVAL->ErrPrefix = newSVsv(errprefix) ;
1603
SvPOK_only(RETVAL->ErrPrefix) ;
1605
if (RETVAL->ErrPrefix)
1606
RETVAL->Env->db_errpfx = SvPVX(RETVAL->ErrPrefix) ;
1608
SetValue_pv(errfile, "ErrFile", char *) ;
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));
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)) ;
1620
hash_store_iv("BerkeleyDB::Term::Env", (char *)RETVAL, 1) ;
1622
if (RETVAL->ErrHandle)
1623
fclose(RETVAL->ErrHandle) ;
1624
if (RETVAL->ErrPrefix)
1625
SvREFCNT_dec(RETVAL->ErrPrefix) ;
1626
Safefree(RETVAL->Env) ;
1631
#else /* DB_VERSION_MAJOR > 2 */
1632
#ifndef AT_LEAST_DB_3_1
1633
# define DB_CLIENT 0
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))) ;
1639
#ifdef AT_LEAST_DB_3_3
1640
env->set_alloc(env, safemalloc, MyRealloc, safefree) ;
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)));
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)));
1653
#ifdef AT_LEAST_DB_4
1654
/* set the server */
1655
if (server && status == 0)
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))) ;
1662
# if defined(AT_LEAST_DB_3_1) && ! defined(AT_LEAST_DB_4)
1663
/* set the server */
1664
if (server && status == 0)
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))) ;
1672
#ifdef AT_LEAST_DB_3_2
1673
if (setflags && status == 0)
1675
status = env->set_flags(env, setflags, 1);
1676
Trace(("ENV->set_flags value = %d returned %s\n", setflags,
1677
my_db_strerror(status))) ;
1683
/* Take a copy of the error prefix */
1685
Trace(("copying errprefix\n" )) ;
1686
RETVAL->ErrPrefix = newSVsv(errprefix) ;
1687
SvPOK_only(RETVAL->ErrPrefix) ;
1689
if (RETVAL->ErrPrefix)
1690
env->set_errpfx(env, SvPVX(RETVAL->ErrPrefix)) ;
1692
SetValue_pv(errfile, "ErrFile", char *) ;
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) ;
1700
SetValue_iv(mode, "Mode") ;
1701
env->set_errcall(env, db_errcall_cb) ;
1702
RETVAL->active = TRUE ;
1704
status = (env->open)(env, home, config, flags, mode) ;
1706
status = (env->open)(env, home, flags, mode) ;
1708
Trace(("ENV->open returned %s\n", my_db_strerror(status))) ;
1712
hash_store_iv("BerkeleyDB::Term::Env", (char *)RETVAL, 1) ;
1714
(env->close)(env, 0) ;
1715
if (RETVAL->ErrHandle)
1716
fclose(RETVAL->ErrHandle) ;
1717
if (RETVAL->ErrPrefix)
1718
SvREFCNT_dec(RETVAL->ErrPrefix) ;
1722
#endif /* DB_VERSION_MAJOR > 2 */
1728
log_archive(env, flags=0)
1736
#ifndef AT_LEAST_DB_3
1737
softCrash("log_archive needs at least Berkeley DB 3.x.x");
1739
# ifdef AT_LEAST_DB_4
1740
env->Status = env->Env->log_archive(env->Env, &list, flags) ;
1742
# ifdef AT_LEAST_DB_3_3
1743
env->Status = log_archive(env->Env, &list, flags) ;
1745
env->Status = log_archive(env->Env, &list, flags, safemalloc) ;
1748
if (env->Status == 0 && list != NULL)
1750
for (file = list; *file != NULL; ++file)
1752
XPUSHs(sv_2mortal(newSVpv(*file, 0))) ;
1759
BerkeleyDB::Txn::Raw
1760
_txn_begin(env, pid=NULL, flags=0)
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") ;
1773
if (!env->txn_enabled)
1774
softCrash("Transaction Manager not enabled") ;
1778
#if DB_VERSION_MAJOR == 2
1779
txn_begin(env->Env->tx_info, p_id, &txn) ;
1781
# ifdef AT_LEAST_DB_4
1782
env->Env->txn_begin(env->Env, p_id, &txn, flags) ;
1784
txn_begin(env->Env, p_id, &txn, flags) ;
1787
if (env->TxnMgrStatus == 0) {
1788
ZMALLOC(RETVAL, BerkeleyDB_Txn_type) ;
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) ;
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)
1807
# ifdef AT_LEAST_DB_3_1
1808
# define env_txn_checkpoint(e,k,m,f) txn_checkpoint(e->Env, k, m, 0)
1810
# define env_txn_checkpoint(e,k,m,f) txn_checkpoint(e->Env, k, m)
1815
env_txn_checkpoint(env, kbyte, min, flags=0)
1824
HV * RETVAL = NULL ;
1827
DB_TXN_STAT * stat ;
1828
#ifdef AT_LEAST_DB_4
1829
if(env->Env->txn_stat(env->Env, &stat, 0) == 0) {
1831
# ifdef AT_LEAST_DB_3_3
1832
if(txn_stat(env->Env, &stat) == 0) {
1834
# if DB_VERSION_MAJOR == 2
1835
if(txn_stat(env->Env->tx_info, &stat, safemalloc) == 0) {
1837
if(txn_stat(env->Env, &stat, safemalloc) == 0) {
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) ;
1861
#define EnDis(x) ((x) ? "Enabled" : "Disabled")
1866
ckActive_Environment(env->active) ;
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) ;
1891
errPrefix(env, prefix)
1895
ckActive_Environment(env->active) ;
1897
if (env->ErrPrefix) {
1898
RETVAL = newSVsv(env->ErrPrefix) ;
1899
SvPOK_only(RETVAL) ;
1900
sv_setsv(env->ErrPrefix, prefix) ;
1904
env->ErrPrefix = newSVsv(prefix) ;
1906
SvPOK_only(env->ErrPrefix) ;
1907
#if DB_VERSION_MAJOR == 2
1908
env->Env->db_errpfx = SvPVX(env->ErrPrefix) ;
1910
env->Env->set_errpfx(env->Env, SvPVX(env->ErrPrefix)) ;
1919
RETVAL = env->Status ;
1928
ckActive_Environment(env->active) ;
1932
softCrash("attempted to close an environment with %d open database(s)",
1934
#endif /* STRICT_CLOSE */
1935
#if DB_VERSION_MAJOR == 2
1936
RETVAL = db_appexit(env->Env) ;
1938
RETVAL = (env->Env->close)(env->Env, 0) ;
1940
env->active = FALSE ;
1941
hash_delete("BerkeleyDB::Term::Env", (char *)env) ;
1951
Trace(("In BerkeleyDB::Env::DESTROY\n"));
1952
Trace((" env %ld Env %ld dirty %d\n", env, &env->Env, PL_dirty)) ;
1954
#if DB_VERSION_MAJOR == 2
1955
db_appexit(env->Env) ;
1957
(env->Env->close)(env->Env, 0) ;
1960
fclose(env->ErrHandle) ;
1962
SvREFCNT_dec(env->ErrPrefix) ;
1963
#if DB_VERSION_MAJOR == 2
1964
Safefree(env->Env) ;
1967
hash_delete("BerkeleyDB::Term::Env", (char *)env) ;
1968
Trace(("End of BerkeleyDB::Env::DESTROY %d\n", RETVAL)) ;
1970
BerkeleyDB::TxnMgr::Raw
1974
ckActive_Environment(env->active) ;
1975
if (!env->txn_enabled)
1976
softCrash("Transaction Manager not enabled") ;
1978
ZMALLOC(RETVAL, BerkeleyDB_TxnMgr_type) ;
1980
/* hash_store_iv("BerkeleyDB::Term::TxnMgr", (char *)txn, 1) ; */
1985
set_lg_dir(env, dir)
1989
ckActive_Database(env->active) ;
1991
#ifndef AT_LEAST_DB_3_1
1992
softCrash("$env->set_lg_dir needs Berkeley DB 3.1 or better") ;
1994
RETVAL = env->Status = env->Env->set_lg_dir(env->Env, dir);
2000
set_lg_bsize(env, bsize)
2004
ckActive_Database(env->active) ;
2006
#ifndef AT_LEAST_DB_3
2007
softCrash("$env->set_lg_bsize needs Berkeley DB 3.0.55 or better") ;
2009
RETVAL = env->Status = env->Env->set_lg_bsize(env->Env, bsize);
2015
set_lg_max(env, lg_max)
2019
ckActive_Database(env->active) ;
2021
#ifndef AT_LEAST_DB_3
2022
softCrash("$env->set_lg_max needs Berkeley DB 3.0.55 or better") ;
2024
RETVAL = env->Status = env->Env->set_lg_max(env->Env, lg_max);
2030
set_data_dir(env, dir)
2034
ckActive_Database(env->active) ;
2036
#ifndef AT_LEAST_DB_3_1
2037
softCrash("$env->set_data_dir needs Berkeley DB 3.1 or better") ;
2039
RETVAL = env->Status = env->Env->set_data_dir(env->Env, dir);
2045
set_tmp_dir(env, dir)
2049
ckActive_Database(env->active) ;
2051
#ifndef AT_LEAST_DB_3_1
2052
softCrash("$env->set_tmp_dir needs Berkeley DB 3.1 or better") ;
2054
RETVAL = env->Status = env->Env->set_tmp_dir(env->Env, dir);
2060
set_mutexlocks(env, do_lock)
2064
ckActive_Database(env->active) ;
2066
#ifndef AT_LEAST_DB_3
2067
softCrash("$env->set_setmutexlocks needs Berkeley DB 3.0 or better") ;
2069
# ifdef AT_LEAST_DB_4
2070
RETVAL = env->Status = env->Env->set_flags(env->Env, DB_NOLOCKING, do_lock);
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);
2083
set_verbose(env, which, onoff)
2088
ckActive_Database(env->active) ;
2090
#ifndef AT_LEAST_DB_3
2091
softCrash("$env->set_verbose needs Berkeley DB 3.x or better") ;
2093
RETVAL = env->Status = env->Env->set_verbose(env->Env, which, onoff);
2099
set_flags(env, flags, onoff)
2104
ckActive_Database(env->active) ;
2106
#ifndef AT_LEAST_DB_3_2
2107
softCrash("$env->set_flags needs Berkeley DB 3.2.x or better") ;
2109
RETVAL = env->Status = env->Env->set_flags(env->Env, flags, onoff);
2115
MODULE = BerkeleyDB::Term PACKAGE = BerkeleyDB::Term
2120
#define safeCroak(string) softCrash(string)
2125
MODULE = BerkeleyDB::Hash PACKAGE = BerkeleyDB::Hash PREFIX = hash_
2127
BerkeleyDB::Hash::Raw
2128
_db_open_hash(self, ref)
2136
BerkeleyDB__Env dbenv = NULL;
2137
SV * ref_dbenv = NULL;
2138
const char * file = NULL ;
2139
const char * subname = NULL ;
2143
BerkeleyDB__Txn txn = NULL ;
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) ;
2152
SetValue_iv(flags, "Flags") ;
2153
SetValue_iv(mode, "Mode") ;
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) ;
2167
/* DB_DUPSORT was introduced in DB 2.5.9 */
2168
if ((sv = readHash(hash, "DupCompare")) && sv != &PL_sv_undef) {
2170
info.dup_compare = dup_compare ;
2171
db->dup_compare = newSVsv(sv) ;
2172
info.flags |= DB_DUP|DB_DUPSORT ;
2174
croak("DupCompare needs Berkeley DB 2.5.9 or later") ;
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")) ;
2185
db_stat(db, flags=0)
2187
BerkeleyDB::Common db
2188
HV * RETVAL = NULL ;
2190
ckActive_Database(db->active) ;
2193
#if DB_VERSION_MAJOR == 2
2194
softCrash("$db->db_stat for a Hash needs Berkeley DB 3.x or better") ;
2196
DB_HASH_STAT * stat ;
2197
#ifdef AT_LEAST_DB_3_3
2198
db->Status = ((db->dbp)->stat)(db->dbp, &stat, flags) ;
2200
db->Status = ((db->dbp)->stat)(db->dbp, &stat, safemalloc, flags) ;
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);
2211
hv_store_iv(RETVAL, "hash_nrecs", stat->hash_nrecs);
2213
#ifndef AT_LEAST_DB_3_1
2214
hv_store_iv(RETVAL, "hash_nelem", stat->hash_nelem);
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);
2237
MODULE = BerkeleyDB::Unknown PACKAGE = BerkeleyDB::Unknown PREFIX = hash_
2240
_db_open_unknown(ref)
2247
BerkeleyDB__Env dbenv = NULL;
2248
SV * ref_dbenv = NULL;
2249
const char * file = NULL ;
2250
const char * subname = NULL ;
2255
BerkeleyDB__Txn txn = NULL ;
2256
static char * Names[] = {"", "Btree", "Hash", "Recno"} ;
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) ;
2264
SetValue_iv(flags, "Flags") ;
2265
SetValue_iv(mode, "Mode") ;
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) ;
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))));
2279
XPUSHs(sv_2mortal(newSVpv(Names[RETVAL->type], 0))) ;
2281
XPUSHs(sv_2mortal(newSViv((IV)NULL)));
2286
MODULE = BerkeleyDB::Btree PACKAGE = BerkeleyDB::Btree PREFIX = btree_
2288
BerkeleyDB::Btree::Raw
2289
_db_open_btree(self, ref)
2297
BerkeleyDB__Env dbenv = NULL;
2298
SV * ref_dbenv = NULL;
2299
const char * file = NULL ;
2300
const char * subname = NULL ;
2304
BerkeleyDB__Txn txn = NULL ;
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) ;
2313
SetValue_iv(flags, "Flags") ;
2314
SetValue_iv(mode, "Mode") ;
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) ;
2328
/* DB_DUPSORT was introduced in DB 2.5.9 */
2329
if ((sv = readHash(hash, "DupCompare")) && sv != &PL_sv_undef) {
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 ;
2336
softCrash("DupCompare needs Berkeley DB 2.5.9 or later") ;
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) ;
2345
RETVAL = my_db_open(db, ref, ref_dbenv, dbenv, txn, file, subname, DB_BTREE, flags, mode, &info) ;
2352
db_stat(db, flags=0)
2354
BerkeleyDB::Common db
2355
HV * RETVAL = NULL ;
2357
ckActive_Database(db->active) ;
2360
DB_BTREE_STAT * stat ;
2361
#ifdef AT_LEAST_DB_3_3
2362
db->Status = ((db->dbp)->stat)(db->dbp, &stat, flags) ;
2364
db->Status = ((db->dbp)->stat)(db->dbp, &stat, safemalloc, flags) ;
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) ;
2374
hv_store_iv(RETVAL, "bt_flags", stat->bt_flags) ;
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);
2386
hv_store_iv(RETVAL, "bt_nrecs", stat->bt_nrecs);
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);
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);
2416
MODULE = BerkeleyDB::Recno PACKAGE = BerkeleyDB::Recno PREFIX = recno_
2418
BerkeleyDB::Recno::Raw
2419
_db_open_recno(self, ref)
2427
BerkeleyDB__Env dbenv = NULL;
2428
SV * ref_dbenv = NULL;
2429
const char * file = NULL ;
2430
const char * subname = NULL ;
2434
BerkeleyDB__Txn txn = NULL ;
2436
hash = (HV*) SvRV(ref) ;
2437
SetValue_pv(file, "Fname", char*) ;
2438
SetValue_ov(dbenv, "Env", BerkeleyDB__Env) ;
2440
SetValue_ov(txn, "Txn", BerkeleyDB__Txn) ;
2441
SetValue_iv(flags, "Flags") ;
2442
SetValue_iv(mode, "Mode") ;
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") ;
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) ;
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) ;
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) ;
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 */
2470
RETVAL = my_db_open(db, ref, ref_dbenv, dbenv, txn, file, subname, DB_RECNO, flags, mode, &info) ;
2476
MODULE = BerkeleyDB::Queue PACKAGE = BerkeleyDB::Queue PREFIX = recno_
2478
BerkeleyDB::Queue::Raw
2479
_db_open_queue(self, ref)
2484
#ifndef AT_LEAST_DB_3
2485
softCrash("BerkeleyDB::Queue needs Berkeley DB 3.0.x or better");
2490
BerkeleyDB__Env dbenv = NULL;
2491
SV * ref_dbenv = NULL;
2492
const char * file = NULL ;
2493
const char * subname = NULL ;
2497
BerkeleyDB__Txn txn = NULL ;
2499
hash = (HV*) SvRV(ref) ;
2500
SetValue_pv(file, "Fname", char*) ;
2501
SetValue_ov(dbenv, "Env", BerkeleyDB__Env) ;
2503
SetValue_ov(txn, "Txn", BerkeleyDB__Txn) ;
2504
SetValue_iv(flags, "Flags") ;
2505
SetValue_iv(mode, "Mode") ;
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") ;
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) ;
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) ;
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 */
2530
RETVAL = my_db_open(db, ref, ref_dbenv, dbenv, txn, file, subname, DB_QUEUE, flags, mode, &info) ;
2537
db_stat(db, flags=0)
2539
BerkeleyDB::Common db
2540
HV * RETVAL = NULL ;
2542
ckActive_Database(db->active) ;
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) ;
2552
db->Status = ((db->dbp)->stat)(db->dbp, &stat, safemalloc, flags) ;
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);
2562
hv_store_iv(RETVAL, "qs_nrecs", stat->qs_nrecs);
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
2571
hv_store_iv(RETVAL, "qs_start", stat->qs_start);
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);
2586
MODULE = BerkeleyDB::Common PACKAGE = BerkeleyDB::Common PREFIX = dab_
2590
db_close(db,flags=0)
2592
BerkeleyDB::Common db
2594
ckActive_Database(db->active) ;
2597
Trace(("BerkeleyDB::Common::db_close %d\n", db));
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)",
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"));
2617
BerkeleyDB::Common db
2620
Trace(("In BerkeleyDB::Common::_DESTROY db %d dirty=%d\n", db, PL_dirty)) ;
2622
Trace(("End of BerkeleyDB::Common::DESTROY \n")) ;
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)
2627
#define db_cursor(db, txn, cur,flags) ((db->dbp)->cursor)(db->dbp, txn, cur,flags)
2629
BerkeleyDB::Cursor::Raw
2630
_db_cursor(db, flags=0)
2632
BerkeleyDB::Common db
2633
BerkeleyDB::Cursor RETVAL = NULL ;
2635
ckActive_Database(db->active) ;
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;
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 ;
2672
/* RETVAL->info ; */
2673
hash_store_iv("BerkeleyDB::Term::Cursor", (char *)RETVAL, 1) ;
2679
BerkeleyDB::Cursor::Raw
2680
_db_join(db, cursors, flags=0)
2682
BerkeleyDB::Common db
2684
BerkeleyDB::Cursor RETVAL = NULL ;
2686
ckActive_Database(db->active) ;
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 */
2693
DBC ** cursor_list ;
2694
I32 count = av_len(cursors) + 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 ;
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){
2710
if ((db->Status = ((db->dbp)->join)(db->dbp, cursor_list, &join_cursor, flags)) == 0){
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;
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 ;
2741
/* RETVAL->info ; */
2742
hash_store_iv("BerkeleyDB::Term::Cursor", (char *)RETVAL, 1) ;
2744
safefree(cursor_list) ;
2745
#endif /* Berkeley DB >= 2.5.2 */
2752
BerkeleyDB::Common db
2754
ckActive_Database(db->active) ;
2756
#ifdef ALLOW_RECNO_OFFSET
2757
RETVAL = db->array_base ? 0 : 1 ;
2760
#endif /* ALLOW_RECNO_OFFSET */
2766
BerkeleyDB::Common db
2768
ckActive_Database(db->active) ;
2776
BerkeleyDB::Common db
2778
ckActive_Database(db->active) ;
2780
#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
2781
softCrash("byteswapped needs Berkeley DB 2.5 or later") ;
2783
#if DB_VERSION_MAJOR == 2
2784
RETVAL = db->dbp->byteswapped ;
2786
#ifdef AT_LEAST_DB_3_3
2787
db->dbp->get_byteswapped(db->dbp, &RETVAL) ;
2789
RETVAL = db->dbp->get_byteswapped(db->dbp) ;
2798
BerkeleyDB::Common db
2800
RETVAL = db->Status ;
2804
#ifdef DBM_FILTERING
2806
#define setFilter(ftype) \
2809
RETVAL = sv_mortalcopy(db->ftype) ; \
2811
if (db->ftype && (code == &PL_sv_undef)) { \
2812
SvREFCNT_dec(db->ftype) ; \
2813
db->ftype = NULL ; \
2817
sv_setsv(db->ftype, code) ; \
2819
db->ftype = newSVsv(code) ; \
2825
filter_fetch_key(db, code)
2826
BerkeleyDB::Common db
2828
SV * RETVAL = &PL_sv_undef ;
2830
DBM_setFilter(db->filter_fetch_key, code) ;
2833
filter_store_key(db, code)
2834
BerkeleyDB::Common db
2836
SV * RETVAL = &PL_sv_undef ;
2838
DBM_setFilter(db->filter_store_key, code) ;
2841
filter_fetch_value(db, code)
2842
BerkeleyDB::Common db
2844
SV * RETVAL = &PL_sv_undef ;
2846
DBM_setFilter(db->filter_fetch_value, code) ;
2849
filter_store_value(db, code)
2850
BerkeleyDB::Common db
2852
SV * RETVAL = &PL_sv_undef ;
2854
DBM_setFilter(db->filter_store_value, code) ;
2856
#endif /* DBM_FILTERING */
2859
partial_set(db, offset, length)
2860
BerkeleyDB::Common db
2864
ckActive_Database(db->active) ;
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))) ;
2871
db->partial = DB_DBT_PARTIAL ;
2878
BerkeleyDB::Common db
2880
ckActive_Database(db->active) ;
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))) ;
2892
#define db_del(db, key, flags) \
2893
(db->Status = ((db->dbp)->del)(db->dbp, db->txn, &key, flags))
2895
db_del(db, key, flags=0)
2897
BerkeleyDB::Common db
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) ;
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))
2909
# define writeToKey() (flagSet(DB_CONSUME)||flagSet(DB_GET_BOTH)||flagSet(DB_SET_RECNO))
2912
#define writeToKey() (flagSet(DB_GET_BOTH)||flagSet(DB_SET_RECNO))
2914
#define db_get(db, key, data, flags) \
2915
(db->Status = ((db->dbp)->get)(db->dbp, db->txn, &key, &data, flags))
2917
db_get(db, key, data, flags=0)
2919
BerkeleyDB::Common db
2923
ckActive_Database(db->active) ;
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));
2931
key if (writeToKey()) OutputKey(ST(1), key) ;
2934
#define db_pget(db, key, pkey, data, flags) \
2935
(db->Status = ((db->dbp)->pget)(db->dbp, db->txn, &key, &pkey, &data, flags))
2937
db_pget(db, key, pkey, data, flags=0)
2939
BerkeleyDB::Common db
2941
DBTKEY_B pkey = NO_INIT
2944
#ifndef AT_LEAST_DB_3_3
2945
softCrash("db_pget needs at least Berkeley DB 3.3");
2947
Trace(("db_pget db [%p] in [%p] txn [%p] flags [%d]\n", db->dbp, db, db->txn, flags)) ;
2948
ckActive_Database(db->active) ;
2950
SetPartial(data,db) ;
2952
RETVAL = db_pget(db, key, pkey, data, flags);
2953
Trace((" RETVAL %d\n", RETVAL));
2957
key if (writeToKey()) OutputKey(ST(1), key) ;
2961
#define db_put(db,key,data,flag) \
2962
(db->Status = (db->dbp->put)(db->dbp,db->txn,&key,&data,flag))
2964
db_put(db, key, data, flags=0)
2966
BerkeleyDB::Common db
2970
ckActive_Database(db->active) ;
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));
2978
key if (flagSet(DB_APPEND)) OutputKey(ST(1), key) ;
2980
#define db_key_range(db, key, range, flags) \
2981
(db->Status = ((db->dbp)->key_range)(db->dbp, db->txn, &key, &range, flags))
2983
db_key_range(db, key, less, equal, greater, flags=0)
2985
BerkeleyDB::Common db
2988
double equal = 0.0 ;
2989
double greater = 0.0 ;
2992
#ifndef AT_LEAST_DB_3_1
2993
softCrash("key_range needs Berkeley DB 3.1.x or later") ;
2995
DB_KEY_RANGE range ;
2996
range.less = range.equal = range.greater = 0.0 ;
2997
ckActive_Database(db->active) ;
2999
RETVAL = db_key_range(db, key, range, flags);
3002
equal = range.equal;
3003
greater = range.greater;
3014
#define db_fd(d, x) (db->Status = (db->dbp->fd)(db->dbp, &x))
3017
BerkeleyDB::Common db
3019
ckActive_Database(db->active) ;
3027
#define db_sync(db, fl) (db->Status = (db->dbp->sync)(db->dbp, fl))
3029
db_sync(db, flags=0)
3031
BerkeleyDB::Common db
3033
ckActive_Database(db->active) ;
3038
BerkeleyDB::Common db
3041
ckActive_Database(db->active) ;
3044
Trace(("_Txn[%p] in[%p] active [%d]\n", txn->txn, txn, txn->active));
3045
ckActive_Transaction(txn->active) ;
3046
db->txn = txn->txn ;
3049
Trace(("_Txn[undef] \n"));
3054
#define db_truncate(db, countp, flags) \
3055
(db->Status = ((db->dbp)->truncate)(db->dbp, db->txn, &countp, flags))
3057
truncate(db, countp, flags=0)
3058
BerkeleyDB::Common db
3062
ckActive_Database(db->active) ;
3064
#ifndef AT_LEAST_DB_3_3
3065
softCrash("truncate needs Berkeley DB 3.3 or later") ;
3068
RETVAL = db_truncate(db, countp, flags);
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))
3078
# define db_associate(db, sec, cb, flags)\
3079
(db->Status = ((db->dbp)->associate)(db->dbp, sec->dbp, &cb, flags))
3082
associate(db, secondary, callback, flags=0)
3083
BerkeleyDB::Common db
3084
BerkeleyDB::Common secondary
3088
ckActive_Database(db->active) ;
3090
#ifndef AT_LEAST_DB_3_3
3091
softCrash("associate needs Berkeley DB 3.3 or later") ;
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);
3104
MODULE = BerkeleyDB::Cursor PACKAGE = BerkeleyDB::Cursor PREFIX = cu_
3106
BerkeleyDB::Cursor::Raw
3109
BerkeleyDB::Cursor db
3110
BerkeleyDB::Cursor RETVAL = NULL ;
3112
CurrentDB = db->parent_db ;
3113
ckActive_Database(db->active) ;
3116
#ifndef AT_LEAST_DB_3
3117
softCrash("c_dup needs at least Berkeley DB 3.0.x");
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 ;
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) ;
3161
BerkeleyDB::Cursor db
3163
CurrentDB = db->parent_db ;
3164
ckActive_Cursor(db->active) ;
3165
hash_delete("BerkeleyDB::Term::Cursor", (char *)db) ;
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 ;
3177
BerkeleyDB::Cursor db
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) ;
3183
((db->cursor)->c_close)(db->cursor) ;
3184
if (db->parent_db->open_cursors)
3185
-- db->parent_db->open_cursors ;
3186
Safefree(db->filename) ;
3188
Trace(("End of BerkeleyDB::Cursor::_DESTROY\n")) ;
3192
BerkeleyDB::Cursor db
3194
RETVAL = db->Status ;
3199
#define cu_c_del(c,f) (c->Status = ((c->cursor)->c_del)(c->cursor,f))
3201
cu_c_del(db, flags=0)
3203
BerkeleyDB::Cursor db
3205
CurrentDB = db->parent_db ;
3206
ckActive_Cursor(db->active) ;
3211
#define cu_c_get(c,k,d,f) (c->Status = (c->cursor->c_get)(c->cursor,&k,&d,f))
3213
cu_c_get(db, key, data, flags=0)
3215
BerkeleyDB::Cursor db
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")) ;
3227
data if (! flagSet(DB_JOIN_ITEM)) OutputValue_B(ST(2), data) ;
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))
3231
cu_c_pget(db, key, pkey, data, flags=0)
3233
BerkeleyDB::Cursor db
3235
DBTKEY_B pkey = NO_INIT
3238
#ifndef AT_LEAST_DB_3_3
3239
softCrash("db_c_pget needs at least Berkeley DB 3.3");
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) ;
3246
RETVAL = cu_c_pget(db, key, pkey, data, flags);
3247
Trace(("c_pget end\n")) ;
3253
data if (! flagSet(DB_JOIN_ITEM)) OutputValue_B(ST(2), data) ;
3257
#define cu_c_put(c,k,d,f) (c->Status = (c->cursor->c_put)(c->cursor,&k,&d,f))
3259
cu_c_put(db, key, data, flags=0)
3261
BerkeleyDB::Cursor db
3265
CurrentDB = db->parent_db ;
3266
ckActive_Cursor(db->active) ;
3267
/* SetPartial(data,db) ; */
3271
#define cu_c_count(c,p,f) (c->Status = (c->cursor->c_count)(c->cursor,&p,f))
3273
cu_c_count(db, count, flags=0)
3275
BerkeleyDB::Cursor db
3276
u_int32_t count = NO_INIT
3278
#ifndef AT_LEAST_DB_3_1
3279
softCrash("c_count needs at least Berkeley DB 3.1.x");
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)) ;
3291
MODULE = BerkeleyDB::TxnMgr PACKAGE = BerkeleyDB::TxnMgr PREFIX = xx_
3293
BerkeleyDB::Txn::Raw
3294
_txn_begin(txnmgr, pid=NULL, flags=0)
3296
BerkeleyDB::TxnMgr txnmgr
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") ;
3308
txnmgr->env->TxnMgrStatus =
3309
#if DB_VERSION_MAJOR == 2
3310
txn_begin(txnmgr->env->Env->tx_info, p_id, &txn) ;
3312
# ifdef AT_LEAST_DB_4
3313
txnmgr->env->Env->txn_begin(txnmgr->env->Env, p_id, &txn, flags) ;
3315
txn_begin(txnmgr->env->Env, p_id, &txn, flags) ;
3318
if (txnmgr->env->TxnMgrStatus == 0) {
3319
ZMALLOC(RETVAL, BerkeleyDB_Txn_type) ;
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) ;
3334
BerkeleyDB::TxnMgr mgr
3336
RETVAL = mgr->env->TxnMgrStatus ;
3343
BerkeleyDB::TxnMgr mgr
3345
Trace(("In BerkeleyDB::TxnMgr::DESTROY dirty=%d\n", PL_dirty)) ;
3347
Trace(("End of BerkeleyDB::TxnMgr::DESTROY\n")) ;
3351
BerkeleyDB::TxnMgr txnp
3355
#if DB_VERSION_MAJOR == 2
3356
# define xx_txn_checkpoint(t,k,m,f) txn_checkpoint(t->env->Env->tx_info, k, m)
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)
3361
# ifdef AT_LEAST_DB_3_1
3362
# define xx_txn_checkpoint(t,k,m,f) txn_checkpoint(t->env->Env, k, m, 0)
3364
# define xx_txn_checkpoint(t,k,m,f) txn_checkpoint(t->env->Env, k, m)
3369
xx_txn_checkpoint(txnp, kbyte, min, flags=0)
3370
BerkeleyDB::TxnMgr txnp
3377
BerkeleyDB::TxnMgr txnp
3378
HV * RETVAL = NULL ;
3381
DB_TXN_STAT * stat ;
3382
#ifdef AT_LEAST_DB_4
3383
if(txnp->env->Env->txn_stat(txnp->env->Env, &stat, 0) == 0) {
3385
# ifdef AT_LEAST_DB_3_3
3386
if(txn_stat(txnp->env->Env, &stat) == 0) {
3388
# if DB_VERSION_MAJOR == 2
3389
if(txn_stat(txnp->env->Env->tx_info, &stat, safemalloc) == 0) {
3391
if(txn_stat(txnp->env->Env, &stat, safemalloc) == 0) {
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) ;
3417
txn_open(dir, flags, mode, dbenv)
3421
BerkeleyDB::Env dbenv
3425
MODULE = BerkeleyDB::Txn PACKAGE = BerkeleyDB::Txn PREFIX = xx_
3431
RETVAL = tid->Status ;
3439
Trace(("In BerkeleyDB::Txn::_DESTROY txn [%d] active [%d] dirty=%d\n", tid->txn, tid->active, PL_dirty)) ;
3441
#ifdef AT_LEAST_DB_4
3442
tid->txn->abort(tid->txn) ;
3444
txn_abort(tid->txn) ;
3447
hash_delete("BerkeleyDB::Term::Txn", (char *)tid) ;
3449
Trace(("End of BerkeleyDB::Txn::DESTROY\n")) ;
3453
#define xx_txn_unlink(d,f,e) txn_unlink(d,f,&(e->Env))
3455
xx_txn_unlink(dir, force, dbenv)
3458
BerkeleyDB::Env dbenv
3461
#ifdef AT_LEAST_DB_4
3462
# define xx_txn_prepare(t) (t->Status = t->txn->prepare(t->txn, 0))
3464
# ifdef AT_LEAST_DB_3_3
3465
# define xx_txn_prepare(t) (t->Status = txn_prepare(t->txn, 0))
3467
# define xx_txn_prepare(t) (t->Status = txn_prepare(t->txn))
3474
ckActive_Transaction(tid->active) ;
3476
#ifdef AT_LEAST_DB_4
3477
# define _txn_commit(t,flags) (t->Status = t->txn->commit(t->txn, flags))
3479
# if DB_VERSION_MAJOR == 2
3480
# define _txn_commit(t,flags) (t->Status = txn_commit(t->txn))
3482
# define _txn_commit(t, flags) (t->Status = txn_commit(t->txn, flags))
3486
_txn_commit(tid, flags=0)
3490
ckActive_Transaction(tid->active) ;
3491
hash_delete("BerkeleyDB::Term::Txn", (char *)tid) ;
3492
tid->active = FALSE ;
3494
#ifdef AT_LEAST_DB_4
3495
# define _txn_abort(t) (t->Status = t->txn->abort(t->txn))
3497
# define _txn_abort(t) (t->Status = txn_abort(t->txn))
3503
ckActive_Transaction(tid->active) ;
3504
hash_delete("BerkeleyDB::Term::Txn", (char *)tid) ;
3505
tid->active = FALSE ;
3507
#ifdef AT_LEAST_DB_4
3508
# define _txn_discard(t,f) (t->Status = t->txn->discard(t->txn, f))
3510
# ifdef AT_LEAST_DB_3_3_4
3511
# define _txn_discard(t,f) (t->Status = txn_discard(t->txn, f))
3513
# define _txn_discard(t,f) (int)softCrash("txn_discard needs Berkeley DB 3.3.4 or better") ;
3517
_txn_discard(tid, flags=0)
3521
ckActive_Transaction(tid->active) ;
3522
hash_delete("BerkeleyDB::Term::Txn", (char *)tid) ;
3523
tid->active = FALSE ;
3525
#ifdef AT_LEAST_DB_4
3526
# define xx_txn_id(t) t->txn->id(t->txn)
3528
# define xx_txn_id(t) txn_id(t->txn)
3534
MODULE = BerkeleyDB::_tiedHash PACKAGE = BerkeleyDB::_tiedHash
3538
BerkeleyDB::Common db
3547
set partial value to 0 - to eliminate the retrieval of
3548
the value need to store any existing partial settings &
3555
/* If necessary create a cursor for FIRSTKEY/NEXTKEY use */
3557
(db->Status = db_cursor(db, db->txn, &cursor, 0)) == 0 )
3558
db->cursor = cursor ;
3561
RETVAL = (db->Status) =
3562
((db->cursor)->c_get)(db->cursor, &key, &value, DB_FIRST);
3564
RETVAL = db->Status ;
3565
/* check for end of cursor */
3566
if (RETVAL == DB_NOTFOUND) {
3567
((db->cursor)->c_close)(db->cursor) ;
3570
ST(0) = sv_newmortal();
3571
OutputKey(ST(0), key)
3578
BerkeleyDB::Common db
3579
DBTKEY key = NO_INIT
3588
RETVAL = (db->Status) =
3589
((db->cursor)->c_get)(db->cursor, &key, &value, DB_NEXT);
3591
/* check for end of cursor */
3592
if (RETVAL == DB_NOTFOUND) {
3593
((db->cursor)->c_close)(db->cursor) ;
3596
ST(0) = sv_newmortal();
3597
OutputKey(ST(0), key)
3600
MODULE = BerkeleyDB::_tiedArray PACKAGE = BerkeleyDB::_tiedArray
3604
BerkeleyDB::Common db
3607
RETVAL = GetArrayLength(db) ;
3612
MODULE = BerkeleyDB PACKAGE = BerkeleyDB
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) ;
3628
if (Major < 2 || (Major == 2 && Minor < 6))
3630
croak("BerkeleyDB needs Berkeley DB 2.6 or greater. This is %d.%d.%d\n",
3631
Major, Minor, Patch) ;
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, "");
3638
empty.data = &zero ;
3639
empty.size = sizeof(db_recno_t) ;