BerkeleyDB.xs
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:98k
源码类别:

MySQL数据库

开发平台:

Visual C++

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