home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.3.4.exe / Apache2 / perl / BerkeleyDB.pm < prev    next >
Encoding:
Perl POD Document  |  2003-11-01  |  31.2 KB  |  1,588 lines

  1.  
  2. package BerkeleyDB;
  3.  
  4.  
  5. #     Copyright (c) 1997-2003 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. #
  9.  
  10. # The documentation for this module is at the bottom of this file,
  11. # after the line __END__.
  12.  
  13. BEGIN { require 5.004_04 }
  14.  
  15. use strict;
  16. use Carp;
  17. use vars qw($VERSION @ISA @EXPORT $AUTOLOAD
  18.         $use_XSLoader);
  19.  
  20. $VERSION = '0.25';
  21.  
  22. require Exporter;
  23. #require DynaLoader;
  24. require AutoLoader;
  25.  
  26. BEGIN {
  27.     $use_XSLoader = 1 ;
  28.     { local $SIG{__DIE__} ; eval { require XSLoader } ; }
  29.  
  30.     if ($@) {
  31.         $use_XSLoader = 0 ;
  32.         require DynaLoader;
  33.         @ISA = qw(DynaLoader);
  34.     }
  35. }
  36.  
  37. @ISA = qw(Exporter DynaLoader);
  38. # Items to export into callers namespace by default. Note: do not export
  39. # names by default without a very good reason. Use EXPORT_OK instead.
  40. # Do not simply export all your public functions/methods/constants.
  41.  
  42. # NOTE -- Do not add to @EXPORT directly. It is written by mkconsts
  43. @EXPORT = qw(
  44.     DB_AFTER
  45.     DB_AGGRESSIVE
  46.     DB_ALREADY_ABORTED
  47.     DB_APPEND
  48.     DB_APPLY_LOGREG
  49.     DB_APP_INIT
  50.     DB_ARCH_ABS
  51.     DB_ARCH_DATA
  52.     DB_ARCH_LOG
  53.     DB_ARCH_REMOVE
  54.     DB_AUTO_COMMIT
  55.     DB_BEFORE
  56.     DB_BROADCAST_EID
  57.     DB_BTREE
  58.     DB_BTREEMAGIC
  59.     DB_BTREEOLDVER
  60.     DB_BTREEVERSION
  61.     DB_CACHED_COUNTS
  62.     DB_CDB_ALLDB
  63.     DB_CHECKPOINT
  64.     DB_CHKSUM
  65.     DB_CHKSUM_SHA1
  66.     DB_CLIENT
  67.     DB_CL_WRITER
  68.     DB_COMMIT
  69.     DB_CONSUME
  70.     DB_CONSUME_WAIT
  71.     DB_CREATE
  72.     DB_CURLSN
  73.     DB_CURRENT
  74.     DB_CXX_NO_EXCEPTIONS
  75.     DB_DELETED
  76.     DB_DELIMITER
  77.     DB_DIRECT
  78.     DB_DIRECT_DB
  79.     DB_DIRECT_LOG
  80.     DB_DIRTY_READ
  81.     DB_DONOTINDEX
  82.     DB_DUP
  83.     DB_DUPCURSOR
  84.     DB_DUPSORT
  85.     DB_EID_BROADCAST
  86.     DB_EID_INVALID
  87.     DB_ENCRYPT
  88.     DB_ENCRYPT_AES
  89.     DB_ENV_APPINIT
  90.     DB_ENV_AUTO_COMMIT
  91.     DB_ENV_CDB
  92.     DB_ENV_CDB_ALLDB
  93.     DB_ENV_CREATE
  94.     DB_ENV_DBLOCAL
  95.     DB_ENV_DIRECT_DB
  96.     DB_ENV_DIRECT_LOG
  97.     DB_ENV_FATAL
  98.     DB_ENV_LOCKDOWN
  99.     DB_ENV_LOCKING
  100.     DB_ENV_LOGGING
  101.     DB_ENV_LOG_AUTOREMOVE
  102.     DB_ENV_NOLOCKING
  103.     DB_ENV_NOMMAP
  104.     DB_ENV_NOPANIC
  105.     DB_ENV_OPEN_CALLED
  106.     DB_ENV_OVERWRITE
  107.     DB_ENV_PANIC_OK
  108.     DB_ENV_PRIVATE
  109.     DB_ENV_REGION_INIT
  110.     DB_ENV_REP_CLIENT
  111.     DB_ENV_REP_LOGSONLY
  112.     DB_ENV_REP_MASTER
  113.     DB_ENV_RPCCLIENT
  114.     DB_ENV_RPCCLIENT_GIVEN
  115.     DB_ENV_STANDALONE
  116.     DB_ENV_SYSTEM_MEM
  117.     DB_ENV_THREAD
  118.     DB_ENV_TIME_NOTGRANTED
  119.     DB_ENV_TXN
  120.     DB_ENV_TXN_NOSYNC
  121.     DB_ENV_TXN_NOT_DURABLE
  122.     DB_ENV_TXN_WRITE_NOSYNC
  123.     DB_ENV_USER_ALLOC
  124.     DB_ENV_YIELDCPU
  125.     DB_EXCL
  126.     DB_EXTENT
  127.     DB_FAST_STAT
  128.     DB_FCNTL_LOCKING
  129.     DB_FILEOPEN
  130.     DB_FILE_ID_LEN
  131.     DB_FIRST
  132.     DB_FIXEDLEN
  133.     DB_FLUSH
  134.     DB_FORCE
  135.     DB_GETREC
  136.     DB_GET_BOTH
  137.     DB_GET_BOTHC
  138.     DB_GET_BOTH_RANGE
  139.     DB_GET_RECNO
  140.     DB_HANDLE_LOCK
  141.     DB_HASH
  142.     DB_HASHMAGIC
  143.     DB_HASHOLDVER
  144.     DB_HASHVERSION
  145.     DB_INCOMPLETE
  146.     DB_INIT_CDB
  147.     DB_INIT_LOCK
  148.     DB_INIT_LOG
  149.     DB_INIT_MPOOL
  150.     DB_INIT_REP
  151.     DB_INIT_TXN
  152.     DB_INVALID_EID
  153.     DB_JAVA_CALLBACK
  154.     DB_JOINENV
  155.     DB_JOIN_ITEM
  156.     DB_JOIN_NOSORT
  157.     DB_KEYEMPTY
  158.     DB_KEYEXIST
  159.     DB_KEYFIRST
  160.     DB_KEYLAST
  161.     DB_LAST
  162.     DB_LOCKDOWN
  163.     DB_LOCKMAGIC
  164.     DB_LOCKVERSION
  165.     DB_LOCK_CONFLICT
  166.     DB_LOCK_DEADLOCK
  167.     DB_LOCK_DEFAULT
  168.     DB_LOCK_DUMP
  169.     DB_LOCK_EXPIRE
  170.     DB_LOCK_FREE_LOCKER
  171.     DB_LOCK_GET
  172.     DB_LOCK_GET_TIMEOUT
  173.     DB_LOCK_INHERIT
  174.     DB_LOCK_MAXLOCKS
  175.     DB_LOCK_MINLOCKS
  176.     DB_LOCK_MINWRITE
  177.     DB_LOCK_NORUN
  178.     DB_LOCK_NOTEXIST
  179.     DB_LOCK_NOTGRANTED
  180.     DB_LOCK_NOTHELD
  181.     DB_LOCK_NOWAIT
  182.     DB_LOCK_OLDEST
  183.     DB_LOCK_PUT
  184.     DB_LOCK_PUT_ALL
  185.     DB_LOCK_PUT_OBJ
  186.     DB_LOCK_PUT_READ
  187.     DB_LOCK_RANDOM
  188.     DB_LOCK_RECORD
  189.     DB_LOCK_REMOVE
  190.     DB_LOCK_RIW_N
  191.     DB_LOCK_RW_N
  192.     DB_LOCK_SET_TIMEOUT
  193.     DB_LOCK_SWITCH
  194.     DB_LOCK_TIMEOUT
  195.     DB_LOCK_TRADE
  196.     DB_LOCK_UPGRADE
  197.     DB_LOCK_UPGRADE_WRITE
  198.     DB_LOCK_YOUNGEST
  199.     DB_LOGC_BUF_SIZE
  200.     DB_LOGFILEID_INVALID
  201.     DB_LOGMAGIC
  202.     DB_LOGOLDVER
  203.     DB_LOGVERSION
  204.     DB_LOG_AUTOREMOVE
  205.     DB_LOG_CHKPNT
  206.     DB_LOG_COMMIT
  207.     DB_LOG_DISK
  208.     DB_LOG_LOCKED
  209.     DB_LOG_NOCOPY
  210.     DB_LOG_NOT_DURABLE
  211.     DB_LOG_PERM
  212.     DB_LOG_SILENT_ERR
  213.     DB_LOG_WRNOSYNC
  214.     DB_MAX_PAGES
  215.     DB_MAX_RECORDS
  216.     DB_MPOOL_CLEAN
  217.     DB_MPOOL_CREATE
  218.     DB_MPOOL_DIRTY
  219.     DB_MPOOL_DISCARD
  220.     DB_MPOOL_EXTENT
  221.     DB_MPOOL_LAST
  222.     DB_MPOOL_NEW
  223.     DB_MPOOL_NEW_GROUP
  224.     DB_MPOOL_NOFILE
  225.     DB_MPOOL_PRIVATE
  226.     DB_MPOOL_UNLINK
  227.     DB_MULTIPLE
  228.     DB_MULTIPLE_KEY
  229.     DB_MUTEXDEBUG
  230.     DB_MUTEXLOCKS
  231.     DB_NEEDSPLIT
  232.     DB_NEXT
  233.     DB_NEXT_DUP
  234.     DB_NEXT_NODUP
  235.     DB_NOCOPY
  236.     DB_NODUPDATA
  237.     DB_NOLOCKING
  238.     DB_NOMMAP
  239.     DB_NOORDERCHK
  240.     DB_NOOVERWRITE
  241.     DB_NOPANIC
  242.     DB_NORECURSE
  243.     DB_NOSERVER
  244.     DB_NOSERVER_HOME
  245.     DB_NOSERVER_ID
  246.     DB_NOSYNC
  247.     DB_NOTFOUND
  248.     DB_NO_AUTO_COMMIT
  249.     DB_ODDFILESIZE
  250.     DB_OK_BTREE
  251.     DB_OK_HASH
  252.     DB_OK_QUEUE
  253.     DB_OK_RECNO
  254.     DB_OLD_VERSION
  255.     DB_OPEN_CALLED
  256.     DB_OPFLAGS_MASK
  257.     DB_ORDERCHKONLY
  258.     DB_OVERWRITE
  259.     DB_PAD
  260.     DB_PAGEYIELD
  261.     DB_PAGE_LOCK
  262.     DB_PAGE_NOTFOUND
  263.     DB_PANIC_ENVIRONMENT
  264.     DB_PERMANENT
  265.     DB_POSITION
  266.     DB_POSITIONI
  267.     DB_PREV
  268.     DB_PREV_NODUP
  269.     DB_PRINTABLE
  270.     DB_PRIORITY_DEFAULT
  271.     DB_PRIORITY_HIGH
  272.     DB_PRIORITY_LOW
  273.     DB_PRIORITY_VERY_HIGH
  274.     DB_PRIORITY_VERY_LOW
  275.     DB_PRIVATE
  276.     DB_PR_HEADERS
  277.     DB_PR_PAGE
  278.     DB_PR_RECOVERYTEST
  279.     DB_QAMMAGIC
  280.     DB_QAMOLDVER
  281.     DB_QAMVERSION
  282.     DB_QUEUE
  283.     DB_RDONLY
  284.     DB_RDWRMASTER
  285.     DB_RECNO
  286.     DB_RECNUM
  287.     DB_RECORDCOUNT
  288.     DB_RECORD_LOCK
  289.     DB_RECOVER
  290.     DB_RECOVER_FATAL
  291.     DB_REGION_ANON
  292.     DB_REGION_INIT
  293.     DB_REGION_MAGIC
  294.     DB_REGION_NAME
  295.     DB_REGISTERED
  296.     DB_RENAMEMAGIC
  297.     DB_RENUMBER
  298.     DB_REP_CLIENT
  299.     DB_REP_CREATE
  300.     DB_REP_DUPMASTER
  301.     DB_REP_HANDLE_DEAD
  302.     DB_REP_HOLDELECTION
  303.     DB_REP_ISPERM
  304.     DB_REP_LOGSONLY
  305.     DB_REP_MASTER
  306.     DB_REP_NEWMASTER
  307.     DB_REP_NEWSITE
  308.     DB_REP_NOBUFFER
  309.     DB_REP_NOTPERM
  310.     DB_REP_OUTDATED
  311.     DB_REP_PERMANENT
  312.     DB_REP_UNAVAIL
  313.     DB_REVSPLITOFF
  314.     DB_RMW
  315.     DB_RPCCLIENT
  316.     DB_RPC_SERVERPROG
  317.     DB_RPC_SERVERVERS
  318.     DB_RUNRECOVERY
  319.     DB_SALVAGE
  320.     DB_SECONDARY_BAD
  321.     DB_SEQUENTIAL
  322.     DB_SET
  323.     DB_SET_LOCK_TIMEOUT
  324.     DB_SET_RANGE
  325.     DB_SET_RECNO
  326.     DB_SET_TXN_NOW
  327.     DB_SET_TXN_TIMEOUT
  328.     DB_SNAPSHOT
  329.     DB_STAT_CLEAR
  330.     DB_SURPRISE_KID
  331.     DB_SWAPBYTES
  332.     DB_SYSTEM_MEM
  333.     DB_TEMPORARY
  334.     DB_TEST_ELECTINIT
  335.     DB_TEST_ELECTSEND
  336.     DB_TEST_ELECTVOTE1
  337.     DB_TEST_ELECTVOTE2
  338.     DB_TEST_ELECTWAIT1
  339.     DB_TEST_ELECTWAIT2
  340.     DB_TEST_POSTDESTROY
  341.     DB_TEST_POSTEXTDELETE
  342.     DB_TEST_POSTEXTOPEN
  343.     DB_TEST_POSTEXTUNLINK
  344.     DB_TEST_POSTLOG
  345.     DB_TEST_POSTLOGMETA
  346.     DB_TEST_POSTOPEN
  347.     DB_TEST_POSTRENAME
  348.     DB_TEST_POSTSYNC
  349.     DB_TEST_PREDESTROY
  350.     DB_TEST_PREEXTDELETE
  351.     DB_TEST_PREEXTOPEN
  352.     DB_TEST_PREEXTUNLINK
  353.     DB_TEST_PREOPEN
  354.     DB_TEST_PRERENAME
  355.     DB_TEST_SUBDB_LOCKS
  356.     DB_THREAD
  357.     DB_TIMEOUT
  358.     DB_TIME_NOTGRANTED
  359.     DB_TRUNCATE
  360.     DB_TXNMAGIC
  361.     DB_TXNVERSION
  362.     DB_TXN_ABORT
  363.     DB_TXN_APPLY
  364.     DB_TXN_BACKWARD_ALLOC
  365.     DB_TXN_BACKWARD_ROLL
  366.     DB_TXN_CKP
  367.     DB_TXN_FORWARD_ROLL
  368.     DB_TXN_GETPGNOS
  369.     DB_TXN_LOCK
  370.     DB_TXN_LOCK_2PL
  371.     DB_TXN_LOCK_MASK
  372.     DB_TXN_LOCK_OPTIMIST
  373.     DB_TXN_LOCK_OPTIMISTIC
  374.     DB_TXN_LOG_MASK
  375.     DB_TXN_LOG_REDO
  376.     DB_TXN_LOG_UNDO
  377.     DB_TXN_LOG_UNDOREDO
  378.     DB_TXN_NOSYNC
  379.     DB_TXN_NOT_DURABLE
  380.     DB_TXN_NOWAIT
  381.     DB_TXN_OPENFILES
  382.     DB_TXN_POPENFILES
  383.     DB_TXN_PRINT
  384.     DB_TXN_REDO
  385.     DB_TXN_SYNC
  386.     DB_TXN_UNDO
  387.     DB_TXN_WRITE_NOSYNC
  388.     DB_UNKNOWN
  389.     DB_UNRESOLVED_CHILD
  390.     DB_UPDATE_SECONDARY
  391.     DB_UPGRADE
  392.     DB_USE_ENVIRON
  393.     DB_USE_ENVIRON_ROOT
  394.     DB_VERB_CHKPOINT
  395.     DB_VERB_DEADLOCK
  396.     DB_VERB_RECOVERY
  397.     DB_VERB_REPLICATION
  398.     DB_VERB_WAITSFOR
  399.     DB_VERIFY
  400.     DB_VERIFY_BAD
  401.     DB_VERIFY_FATAL
  402.     DB_VERSION_MAJOR
  403.     DB_VERSION_MINOR
  404.     DB_VERSION_PATCH
  405.     DB_VERSION_STRING
  406.     DB_VRFY_FLAGMASK
  407.     DB_WRITECURSOR
  408.     DB_WRITELOCK
  409.     DB_WRITEOPEN
  410.     DB_WRNOSYNC
  411.     DB_XA_CREATE
  412.     DB_XIDDATASIZE
  413.     DB_YIELDCPU
  414.     DB_debug_FLAG
  415.     DB_user_BEGIN
  416.     );
  417.  
  418. sub AUTOLOAD {
  419.     my($constname);
  420.     ($constname = $AUTOLOAD) =~ s/.*:://;
  421.     my ($error, $val) = constant($constname);
  422.     Carp::croak $error if $error;
  423.     no strict 'refs';
  424.     *{$AUTOLOAD} = sub { $val };
  425.     goto &{$AUTOLOAD};
  426. }         
  427.  
  428. #bootstrap BerkeleyDB $VERSION;
  429. if ($use_XSLoader)
  430.   { XSLoader::load("BerkeleyDB", $VERSION)}
  431. else
  432.   { bootstrap BerkeleyDB $VERSION }  
  433.  
  434. # Preloaded methods go here.
  435.  
  436.  
  437. sub ParseParameters($@)
  438. {
  439.     my ($default, @rest) = @_ ;
  440.     my (%got) = %$default ;
  441.     my (@Bad) ;
  442.     my ($key, $value) ;
  443.     my $sub = (caller(1))[3] ;
  444.     my %options = () ;
  445.     local ($Carp::CarpLevel) = 1 ;
  446.  
  447.     # allow the options to be passed as a hash reference or
  448.     # as the complete hash.
  449.     if (@rest == 1) {
  450.  
  451.         croak "$sub: parameter is not a reference to a hash"
  452.             if ref $rest[0] ne "HASH" ;
  453.  
  454.         %options = %{ $rest[0] } ;
  455.     }
  456.     elsif (@rest >= 2) {
  457.         %options = @rest ;
  458.     }
  459.  
  460.     while (($key, $value) = each %options)
  461.     {
  462.     $key =~ s/^-// ;
  463.  
  464.         if (exists $default->{$key})
  465.           { $got{$key} = $value }
  466.         else
  467.       { push (@Bad, $key) }
  468.     }
  469.     
  470.     if (@Bad) {
  471.         my ($bad) = join(", ", @Bad) ;
  472.         croak "unknown key value(s) @Bad" ;
  473.     }
  474.  
  475.     return \%got ;
  476. }
  477.  
  478. sub parseEncrypt
  479. {
  480.     my $got = shift ;
  481.  
  482.  
  483.     if (defined $got->{Encrypt}) {
  484.         croak("Encrypt parameter must be a hash reference")
  485.             if !ref $got->{Encrypt} || ref $got->{Encrypt} ne 'HASH' ;
  486.  
  487.     my %config = %{ $got->{Encrypt} } ;
  488.  
  489.         my $p = BerkeleyDB::ParseParameters({
  490.                     Password    => undef,
  491.                     Flags        => undef,
  492.                 }, %config);
  493.  
  494.         croak("Must specify Password and Flags with Encrypt parameter")
  495.         if ! (defined $p->{Password} && defined $p->{Flags});
  496.  
  497.         $got->{"Enc_Passwd"} = $p->{Password};
  498.         $got->{"Enc_Flags"} = $p->{Flags};
  499.     }
  500. }
  501.  
  502. use UNIVERSAL qw( isa ) ;
  503.  
  504. sub env_remove
  505. {
  506.     # Usage:
  507.     #
  508.     #    $env = new BerkeleyDB::Env
  509.     #            [ -Home        => $path, ]
  510.     #            [ -Config    => { name => value, name => value }
  511.     #            [ -Flags    => DB_INIT_LOCK| ]
  512.     #            ;
  513.  
  514.     my $got = BerkeleyDB::ParseParameters({
  515.                     Home        => undef,
  516.                     Flags         => 0,
  517.                     Config        => undef,
  518.                     }, @_) ;
  519.  
  520.     if (defined $got->{Config}) {
  521.         croak("Config parameter must be a hash reference")
  522.             if ! ref $got->{Config} eq 'HASH' ;
  523.  
  524.         @BerkeleyDB::a = () ;
  525.     my $k = "" ; my $v = "" ;
  526.     while (($k, $v) = each %{$got->{Config}}) {
  527.         push @BerkeleyDB::a, "$k\t$v" ;
  528.     }
  529.  
  530.         $got->{"Config"} = pack("p*", @BerkeleyDB::a, undef) 
  531.         if @BerkeleyDB::a ;
  532.     }
  533.  
  534.     return _env_remove($got) ;
  535. }
  536.  
  537. sub db_remove
  538. {
  539.     my $got = BerkeleyDB::ParseParameters(
  540.               {
  541.             Filename     => undef,
  542.             Subname        => undef,
  543.             Flags        => 0,
  544.             Env        => undef,
  545.               }, @_) ;
  546.  
  547.     croak("Must specify a filename")
  548.     if ! defined $got->{Filename} ;
  549.  
  550.     croak("Env not of type BerkeleyDB::Env")
  551.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  552.  
  553.     return _db_remove($got);
  554. }
  555.  
  556. sub db_rename
  557. {
  558.     my $got = BerkeleyDB::ParseParameters(
  559.               {
  560.             Filename     => undef,
  561.             Subname        => undef,
  562.             Newname        => undef,
  563.             Flags        => 0,
  564.             Env        => undef,
  565.               }, @_) ;
  566.  
  567.     croak("Env not of type BerkeleyDB::Env")
  568.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  569.  
  570.     croak("Must specify a filename")
  571.     if ! defined $got->{Filename} ;
  572.  
  573.     croak("Must specify a Subname")
  574.     if ! defined $got->{Subname} ;
  575.  
  576.     croak("Must specify a Newname")
  577.     if ! defined $got->{Newname} ;
  578.  
  579.     return _db_rename($got);
  580. }
  581.  
  582. sub db_verify
  583. {
  584.     my $got = BerkeleyDB::ParseParameters(
  585.               {
  586.             Filename     => undef,
  587.             Subname        => undef,
  588.             Outfile        => undef,
  589.             Flags        => 0,
  590.             Env        => undef,
  591.               }, @_) ;
  592.  
  593.     croak("Env not of type BerkeleyDB::Env")
  594.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  595.  
  596.     croak("Must specify a filename")
  597.     if ! defined $got->{Filename} ;
  598.  
  599.     return _db_verify($got);
  600. }
  601.  
  602. package BerkeleyDB::Env ;
  603.  
  604. use UNIVERSAL qw( isa ) ;
  605. use Carp ;
  606. use vars qw( %valid_config_keys ) ;
  607.  
  608. sub isaFilehandle
  609. {
  610.     my $fh = shift ;
  611.  
  612.     return ((isa($fh,'GLOB') or isa(\$fh,'GLOB')) and defined fileno($fh) )
  613.  
  614. }
  615.  
  616. %valid_config_keys = map { $_, 1 } qw( DB_DATA_DIR DB_LOG_DIR DB_TEMP_DIR
  617. DB_TMP_DIR ) ;
  618.  
  619. sub new
  620. {
  621.     # Usage:
  622.     #
  623.     #    $env = new BerkeleyDB::Env
  624.     #            [ -Home        => $path, ]
  625.     #            [ -Mode        => mode, ]
  626.     #            [ -Config    => { name => value, name => value }
  627.     #            [ -ErrFile       => filename, ]
  628.     #            [ -ErrPrefix     => "string", ]
  629.     #            [ -Flags    => DB_INIT_LOCK| ]
  630.     #            [ -Set_Flags    => $flags,]
  631.     #            [ -Cachesize    => number ]
  632.     #            [ -LockDetect    =>  ]
  633.     #            [ -Verbose    => boolean ]
  634.     #            [ -Encrypt    => { Password => string, Flags => value}
  635.     #
  636.     #            ;
  637.  
  638.     my $pkg = shift ;
  639.     my $got = BerkeleyDB::ParseParameters({
  640.                     Home        => undef,
  641.                     Server        => undef,
  642.                     Mode        => 0666,
  643.                     ErrFile      => undef,
  644.                     ErrPrefix     => undef,
  645.                     Flags         => 0,
  646.                     SetFlags         => 0,
  647.                     Cachesize         => 0,
  648.                     LockDetect         => 0,
  649.                     Verbose        => 0,
  650.                     Config        => undef,
  651.                     Encrypt        => undef,
  652.                     }, @_) ;
  653.  
  654.     if (defined $got->{ErrFile}) {
  655.         croak("ErrFile parameter must be a file name")
  656.             if ref $got->{ErrFile} ;
  657.     #if (!isaFilehandle($got->{ErrFile})) {
  658.     #    my $handle = new IO::File ">$got->{ErrFile}"
  659. #        or croak "Cannot open file $got->{ErrFile}: $!\n" ;
  660. #        $got->{ErrFile} = $handle ;
  661. #    }
  662.     }
  663.  
  664.     
  665.     my %config ;
  666.     if (defined $got->{Config}) {
  667.         croak("Config parameter must be a hash reference")
  668.             if ! ref $got->{Config} eq 'HASH' ;
  669.  
  670.     %config = %{ $got->{Config} } ;
  671.         @BerkeleyDB::a = () ;
  672.     my $k = "" ; my $v = "" ;
  673.     while (($k, $v) = each %config) {
  674.         if ($BerkeleyDB::db_version >= 3.1 && ! $valid_config_keys{$k} ){
  675.             $BerkeleyDB::Error = "illegal name-value pair: $k $v\n" ; 
  676.                 croak $BerkeleyDB::Error ;
  677.         }
  678.         push @BerkeleyDB::a, "$k\t$v" ;
  679.     }
  680.  
  681.         $got->{"Config"} = pack("p*", @BerkeleyDB::a, undef) 
  682.         if @BerkeleyDB::a ;
  683.     }
  684.  
  685.     BerkeleyDB::parseEncrypt($got);
  686.  
  687.     my ($addr) = _db_appinit($pkg, $got) ;
  688.     my $obj ;
  689.     $obj = bless [$addr] , $pkg if $addr ;
  690.     if ($obj && $BerkeleyDB::db_version >= 3.1 && keys %config) {
  691.     my ($k, $v);
  692.     while (($k, $v) = each %config) {
  693.         if ($k eq 'DB_DATA_DIR')
  694.           { $obj->set_data_dir($v) }
  695.         elsif ($k eq 'DB_LOG_DIR')
  696.           { $obj->set_lg_dir($v) }
  697.         elsif ($k eq 'DB_TEMP_DIR' || $k eq 'DB_TMP_DIR')
  698.           { $obj->set_tmp_dir($v) }
  699.         else {
  700.           $BerkeleyDB::Error = "illegal name-value pair: $k $v\n" ; 
  701.               croak $BerkeleyDB::Error 
  702.             }
  703.     }
  704.     }
  705.     return $obj ;
  706. }
  707.  
  708.  
  709. sub TxnMgr
  710. {
  711.     my $env = shift ;
  712.     my ($addr) = $env->_TxnMgr() ;
  713.     my $obj ;
  714.     $obj = bless [$addr, $env] , "BerkeleyDB::TxnMgr" if $addr ;
  715.     return $obj ;
  716. }
  717.  
  718. sub txn_begin
  719. {
  720.     my $env = shift ;
  721.     my ($addr) = $env->_txn_begin(@_) ;
  722.     my $obj ;
  723.     $obj = bless [$addr, $env] , "BerkeleyDB::Txn" if $addr ;
  724.     return $obj ;
  725. }
  726.  
  727. sub DESTROY
  728. {
  729.     my $self = shift ;
  730.     $self->_DESTROY() ;
  731. }
  732.  
  733. package BerkeleyDB::Hash ;
  734.  
  735. use vars qw(@ISA) ;
  736. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedHash ) ;
  737. use UNIVERSAL qw( isa ) ;
  738. use Carp ;
  739.  
  740. sub new
  741. {
  742.     my $self = shift ;
  743.     my $got = BerkeleyDB::ParseParameters(
  744.               {
  745.             # Generic Stuff
  746.             Filename     => undef,
  747.             Subname        => undef,
  748.             #Flags        => BerkeleyDB::DB_CREATE(),
  749.             Flags        => 0,
  750.             Property    => 0,
  751.             Mode        => 0666,
  752.             Cachesize     => 0,
  753.             Lorder         => 0,
  754.             Pagesize     => 0,
  755.             Env        => undef,
  756.             #Tie         => undef,
  757.             Txn        => undef,
  758.             Encrypt        => undef,
  759.  
  760.             # Hash specific
  761.             Ffactor        => 0,
  762.             Nelem         => 0,
  763.             Hash         => undef,
  764.             DupCompare    => undef,
  765.  
  766.             # BerkeleyDB specific
  767.             ReadKey        => undef,
  768.             WriteKey    => undef,
  769.             ReadValue    => undef,
  770.             WriteValue    => undef,
  771.               }, @_) ;
  772.  
  773.     croak("Env not of type BerkeleyDB::Env")
  774.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  775.  
  776.     croak("Txn not of type BerkeleyDB::Txn")
  777.     if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  778.  
  779.     croak("-Tie needs a reference to a hash")
  780.     if defined $got->{Tie} and $got->{Tie} !~ /HASH/ ;
  781.  
  782.     BerkeleyDB::parseEncrypt($got);
  783.  
  784.     my ($addr) = _db_open_hash($self, $got);
  785.     my $obj ;
  786.     if ($addr) {
  787.         $obj = bless [$addr] , $self ;
  788.     push @{ $obj }, $got->{Env} if $got->{Env} ;
  789.         $obj->Txn($got->{Txn}) 
  790.             if $got->{Txn} ;
  791.     }
  792.     return $obj ;
  793. }
  794.  
  795. *TIEHASH = \&new ;
  796.  
  797.  
  798. package BerkeleyDB::Btree ;
  799.  
  800. use vars qw(@ISA) ;
  801. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedHash ) ;
  802. use UNIVERSAL qw( isa ) ;
  803. use Carp ;
  804.  
  805. sub new
  806. {
  807.     my $self = shift ;
  808.     my $got = BerkeleyDB::ParseParameters(
  809.               {
  810.             # Generic Stuff
  811.             Filename     => undef,
  812.             Subname        => undef,
  813.             #Flags        => BerkeleyDB::DB_CREATE(),
  814.             Flags        => 0,
  815.             Property    => 0,
  816.             Mode        => 0666,
  817.             Cachesize     => 0,
  818.             Lorder         => 0,
  819.             Pagesize     => 0,
  820.             Env        => undef,
  821.             #Tie         => undef,
  822.             Txn        => undef,
  823.             Encrypt        => undef,
  824.  
  825.             # Btree specific
  826.             Minkey        => 0,
  827.             Compare        => undef,
  828.             DupCompare    => undef,
  829.             Prefix         => undef,
  830.               }, @_) ;
  831.  
  832.     croak("Env not of type BerkeleyDB::Env")
  833.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  834.  
  835.     croak("Txn not of type BerkeleyDB::Txn")
  836.     if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  837.  
  838.     croak("-Tie needs a reference to a hash")
  839.     if defined $got->{Tie} and $got->{Tie} !~ /HASH/ ;
  840.  
  841.     BerkeleyDB::parseEncrypt($got);
  842.  
  843.     my ($addr) = _db_open_btree($self, $got);
  844.     my $obj ;
  845.     if ($addr) {
  846.         $obj = bless [$addr] , $self ;
  847.     push @{ $obj }, $got->{Env} if $got->{Env} ;
  848.         $obj->Txn($got->{Txn}) 
  849.             if $got->{Txn} ;
  850.     }
  851.     return $obj ;
  852. }
  853.  
  854. *BerkeleyDB::Btree::TIEHASH = \&BerkeleyDB::Btree::new ;
  855.  
  856.  
  857. package BerkeleyDB::Recno ;
  858.  
  859. use vars qw(@ISA) ;
  860. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
  861. use UNIVERSAL qw( isa ) ;
  862. use Carp ;
  863.  
  864. sub new
  865. {
  866.     my $self = shift ;
  867.     my $got = BerkeleyDB::ParseParameters(
  868.               {
  869.             # Generic Stuff
  870.             Filename     => undef,
  871.             Subname        => undef,
  872.             #Flags        => BerkeleyDB::DB_CREATE(),
  873.             Flags        => 0,
  874.             Property    => 0,
  875.             Mode        => 0666,
  876.             Cachesize     => 0,
  877.             Lorder         => 0,
  878.             Pagesize     => 0,
  879.             Env        => undef,
  880.             #Tie         => undef,
  881.             Txn        => undef,
  882.             Encrypt        => undef,
  883.  
  884.             # Recno specific
  885.             Delim        => undef,
  886.             Len        => undef,
  887.             Pad        => undef,
  888.             Source         => undef,
  889.             ArrayBase     => 1, # lowest index in array
  890.               }, @_) ;
  891.  
  892.     croak("Env not of type BerkeleyDB::Env")
  893.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  894.  
  895.     croak("Txn not of type BerkeleyDB::Txn")
  896.     if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  897.  
  898.     croak("Tie needs a reference to an array")
  899.     if defined $got->{Tie} and $got->{Tie} !~ /ARRAY/ ;
  900.  
  901.     croak("ArrayBase can only be 0 or 1, parsed $got->{ArrayBase}")
  902.     if $got->{ArrayBase} != 1 and $got->{ArrayBase} != 0 ;
  903.  
  904.  
  905.     BerkeleyDB::parseEncrypt($got);
  906.  
  907.     $got->{Fname} = $got->{Filename} if defined $got->{Filename} ;
  908.  
  909.     my ($addr) = _db_open_recno($self, $got);
  910.     my $obj ;
  911.     if ($addr) {
  912.         $obj = bless [$addr] , $self ;
  913.     push @{ $obj }, $got->{Env} if $got->{Env} ;
  914.         $obj->Txn($got->{Txn}) 
  915.             if $got->{Txn} ;
  916.     }    
  917.     return $obj ;
  918. }
  919.  
  920. *BerkeleyDB::Recno::TIEARRAY = \&BerkeleyDB::Recno::new ;
  921. *BerkeleyDB::Recno::db_stat = \&BerkeleyDB::Btree::db_stat ;
  922.  
  923. package BerkeleyDB::Queue ;
  924.  
  925. use vars qw(@ISA) ;
  926. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
  927. use UNIVERSAL qw( isa ) ;
  928. use Carp ;
  929.  
  930. sub new
  931. {
  932.     my $self = shift ;
  933.     my $got = BerkeleyDB::ParseParameters(
  934.               {
  935.             # Generic Stuff
  936.             Filename     => undef,
  937.             Subname        => undef,
  938.             #Flags        => BerkeleyDB::DB_CREATE(),
  939.             Flags        => 0,
  940.             Property    => 0,
  941.             Mode        => 0666,
  942.             Cachesize     => 0,
  943.             Lorder         => 0,
  944.             Pagesize     => 0,
  945.             Env        => undef,
  946.             #Tie         => undef,
  947.             Txn        => undef,
  948.             Encrypt        => undef,
  949.  
  950.             # Queue specific
  951.             Len        => undef,
  952.             Pad        => undef,
  953.             ArrayBase     => 1, # lowest index in array
  954.             ExtentSize      => undef,
  955.               }, @_) ;
  956.  
  957.     croak("Env not of type BerkeleyDB::Env")
  958.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  959.  
  960.     croak("Txn not of type BerkeleyDB::Txn")
  961.     if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  962.  
  963.     croak("Tie needs a reference to an array")
  964.     if defined $got->{Tie} and $got->{Tie} !~ /ARRAY/ ;
  965.  
  966.     croak("ArrayBase can only be 0 or 1, parsed $got->{ArrayBase}")
  967.     if $got->{ArrayBase} != 1 and $got->{ArrayBase} != 0 ;
  968.  
  969.     BerkeleyDB::parseEncrypt($got);
  970.  
  971.     $got->{Fname} = $got->{Filename} if defined $got->{Filename} ;
  972.  
  973.     my ($addr) = _db_open_queue($self, $got);
  974.     my $obj ;
  975.     if ($addr) {
  976.         $obj = bless [$addr] , $self ;
  977.     push @{ $obj }, $got->{Env} if $got->{Env} ;
  978.         $obj->Txn($got->{Txn})
  979.             if $got->{Txn} ;
  980.     }    
  981.     return $obj ;
  982. }
  983.  
  984. *BerkeleyDB::Queue::TIEARRAY = \&BerkeleyDB::Queue::new ;
  985.  
  986. sub UNSHIFT
  987. {
  988.     my $self = shift;
  989.     croak "unshift is unsupported with Queue databases";
  990. }
  991.  
  992. ## package BerkeleyDB::Text ;
  993. ## 
  994. ## use vars qw(@ISA) ;
  995. ## @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
  996. ## use UNIVERSAL qw( isa ) ;
  997. ## use Carp ;
  998. ## 
  999. ## sub new
  1000. ## {
  1001. ##     my $self = shift ;
  1002. ##     my $got = BerkeleyDB::ParseParameters(
  1003. ##               {
  1004. ##             # Generic Stuff
  1005. ##             Filename     => undef,
  1006. ##             #Flags        => BerkeleyDB::DB_CREATE(),
  1007. ##             Flags        => 0,
  1008. ##             Property    => 0,
  1009. ##             Mode        => 0666,
  1010. ##             Cachesize     => 0,
  1011. ##             Lorder         => 0,
  1012. ##             Pagesize     => 0,
  1013. ##             Env        => undef,
  1014. ##             #Tie         => undef,
  1015. ##             Txn        => undef,
  1016. ## 
  1017. ##             # Recno specific
  1018. ##             Delim        => undef,
  1019. ##             Len        => undef,
  1020. ##             Pad        => undef,
  1021. ##             Btree         => undef,
  1022. ##               }, @_) ;
  1023. ## 
  1024. ##     croak("Env not of type BerkeleyDB::Env")
  1025. ##     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  1026. ## 
  1027. ##     croak("Txn not of type BerkeleyDB::Txn")
  1028. ##     if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  1029. ## 
  1030. ##     croak("-Tie needs a reference to an array")
  1031. ##     if defined $got->{Tie} and $got->{Tie} !~ /ARRAY/ ;
  1032. ## 
  1033. ##     # rearange for recno
  1034. ##     $got->{Source} = $got->{Filename} if defined $got->{Filename} ;
  1035. ##     delete $got->{Filename} ;
  1036. ##     $got->{Fname} = $got->{Btree} if defined $got->{Btree} ;
  1037. ##     return BerkeleyDB::Recno::_db_open_recno($self, $got);
  1038. ## }
  1039. ## 
  1040. ## *BerkeleyDB::Text::TIEARRAY = \&BerkeleyDB::Text::new ;
  1041. ## *BerkeleyDB::Text::db_stat = \&BerkeleyDB::Btree::db_stat ;
  1042.  
  1043. package BerkeleyDB::Unknown ;
  1044.  
  1045. use vars qw(@ISA) ;
  1046. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
  1047. use UNIVERSAL qw( isa ) ;
  1048. use Carp ;
  1049.  
  1050. sub new
  1051. {
  1052.     my $self = shift ;
  1053.     my $got = BerkeleyDB::ParseParameters(
  1054.               {
  1055.             # Generic Stuff
  1056.             Filename     => undef,
  1057.             Subname        => undef,
  1058.             #Flags        => BerkeleyDB::DB_CREATE(),
  1059.             Flags        => 0,
  1060.             Property    => 0,
  1061.             Mode        => 0666,
  1062.             Cachesize     => 0,
  1063.             Lorder         => 0,
  1064.             Pagesize     => 0,
  1065.             Env        => undef,
  1066.             #Tie         => undef,
  1067.             Txn        => undef,
  1068.             Encrypt        => undef,
  1069.  
  1070.               }, @_) ;
  1071.  
  1072.     croak("Env not of type BerkeleyDB::Env")
  1073.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  1074.  
  1075.     croak("Txn not of type BerkeleyDB::Txn")
  1076.     if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  1077.  
  1078.     croak("-Tie needs a reference to a hash")
  1079.     if defined $got->{Tie} and $got->{Tie} !~ /HASH/ ;
  1080.  
  1081.     BerkeleyDB::parseEncrypt($got);
  1082.  
  1083.     my ($addr, $type) = _db_open_unknown($got);
  1084.     my $obj ;
  1085.     if ($addr) {
  1086.         $obj = bless [$addr], "BerkeleyDB::$type" ;
  1087.     push @{ $obj }, $got->{Env} if $got->{Env} ;
  1088.         $obj->Txn($got->{Txn})
  1089.             if $got->{Txn} ;
  1090.     }    
  1091.     return $obj ;
  1092. }
  1093.  
  1094.  
  1095. package BerkeleyDB::_tiedHash ;
  1096.  
  1097. use Carp ;
  1098.  
  1099. #sub TIEHASH  
  1100. #{ 
  1101. #    my $self = shift ;
  1102. #    my $db_object = shift ;
  1103. #
  1104. #print "Tiehash REF=[$self] [" . (ref $self) . "]\n" ;
  1105. #
  1106. #    return bless { Obj => $db_object}, $self ; 
  1107. #}
  1108.  
  1109. sub Tie
  1110. {
  1111.     # Usage:
  1112.     #
  1113.     #   $db->Tie \%hash ;
  1114.     #
  1115.  
  1116.     my $self = shift ;
  1117.  
  1118.     #print "Tie method REF=[$self] [" . (ref $self) . "]\n" ;
  1119.  
  1120.     croak("usage \$x->Tie \\%hash\n") unless @_ ;
  1121.     my $ref  = shift ; 
  1122.  
  1123.     croak("Tie needs a reference to a hash")
  1124.     if defined $ref and $ref !~ /HASH/ ;
  1125.  
  1126.     #tie %{ $ref }, ref($self), $self ; 
  1127.     tie %{ $ref }, "BerkeleyDB::_tiedHash", $self ; 
  1128.     return undef ;
  1129. }
  1130.  
  1131.  
  1132. sub TIEHASH  
  1133.     my $self = shift ;
  1134.     my $db_object = shift ;
  1135.     #return bless $db_object, 'BerkeleyDB::Common' ; 
  1136.     return $db_object ;
  1137. }
  1138.  
  1139. sub STORE
  1140. {
  1141.     my $self = shift ;
  1142.     my $key  = shift ;
  1143.     my $value = shift ;
  1144.  
  1145.     $self->db_put($key, $value) ;
  1146. }
  1147.  
  1148. sub FETCH
  1149. {
  1150.     my $self = shift ;
  1151.     my $key  = shift ;
  1152.     my $value = undef ;
  1153.     $self->db_get($key, $value) ;
  1154.  
  1155.     return $value ;
  1156. }
  1157.  
  1158. sub EXISTS
  1159. {
  1160.     my $self = shift ;
  1161.     my $key  = shift ;
  1162.     my $value = undef ;
  1163.     $self->db_get($key, $value) == 0 ;
  1164. }
  1165.  
  1166. sub DELETE
  1167. {
  1168.     my $self = shift ;
  1169.     my $key  = shift ;
  1170.     $self->db_del($key) ;
  1171. }
  1172.  
  1173. sub CLEAR
  1174. {
  1175.     my $self = shift ;
  1176.     my ($key, $value) = (0, 0) ;
  1177.     my $cursor = $self->_db_write_cursor() ;
  1178.     while ($cursor->c_get($key, $value, BerkeleyDB::DB_PREV()) == 0) 
  1179.     { $cursor->c_del() }
  1180. }
  1181.  
  1182. #sub DESTROY
  1183. #{
  1184. #    my $self = shift ;
  1185. #    print "BerkeleyDB::_tieHash::DESTROY\n" ;
  1186. #    $self->{Cursor}->c_close() if $self->{Cursor} ;
  1187. #}
  1188.  
  1189. package BerkeleyDB::_tiedArray ;
  1190.  
  1191. use Carp ;
  1192.  
  1193. sub Tie
  1194. {
  1195.     # Usage:
  1196.     #
  1197.     #   $db->Tie \@array ;
  1198.     #
  1199.  
  1200.     my $self = shift ;
  1201.  
  1202.     #print "Tie method REF=[$self] [" . (ref $self) . "]\n" ;
  1203.  
  1204.     croak("usage \$x->Tie \\%hash\n") unless @_ ;
  1205.     my $ref  = shift ; 
  1206.  
  1207.     croak("Tie needs a reference to an array")
  1208.     if defined $ref and $ref !~ /ARRAY/ ;
  1209.  
  1210.     #tie %{ $ref }, ref($self), $self ; 
  1211.     tie @{ $ref }, "BerkeleyDB::_tiedArray", $self ; 
  1212.     return undef ;
  1213. }
  1214.  
  1215.  
  1216. #sub TIEARRAY  
  1217. #{ 
  1218. #    my $self = shift ;
  1219. #    my $db_object = shift ;
  1220. #
  1221. #print "Tiearray REF=[$self] [" . (ref $self) . "]\n" ;
  1222. #
  1223. #    return bless { Obj => $db_object}, $self ; 
  1224. #}
  1225.  
  1226. sub TIEARRAY  
  1227.     my $self = shift ;
  1228.     my $db_object = shift ;
  1229.     #return bless $db_object, 'BerkeleyDB::Common' ; 
  1230.     return $db_object ;
  1231. }
  1232.  
  1233. sub STORE
  1234. {
  1235.     my $self = shift ;
  1236.     my $key  = shift ;
  1237.     my $value = shift ;
  1238.  
  1239.     $self->db_put($key, $value) ;
  1240. }
  1241.  
  1242. sub FETCH
  1243. {
  1244.     my $self = shift ;
  1245.     my $key  = shift ;
  1246.     my $value = undef ;
  1247.     $self->db_get($key, $value) ;
  1248.  
  1249.     return $value ;
  1250. }
  1251.  
  1252. *CLEAR =    \&BerkeleyDB::_tiedHash::CLEAR ;
  1253. *FIRSTKEY = \&BerkeleyDB::_tiedHash::FIRSTKEY ;
  1254. *NEXTKEY =  \&BerkeleyDB::_tiedHash::NEXTKEY ;
  1255.  
  1256. sub EXTEND {} # don't do anything with EXTEND
  1257.  
  1258.  
  1259. sub SHIFT
  1260. {
  1261.     my $self = shift;
  1262.     my ($key, $value) = (0, 0) ;
  1263.     my $cursor = $self->db_cursor() ;
  1264.     return undef if $cursor->c_get($key, $value, BerkeleyDB::DB_FIRST()) != 0 ;
  1265.     return undef if $cursor->c_del() != 0 ;
  1266.  
  1267.     return $value ;
  1268. }
  1269.  
  1270.  
  1271. sub UNSHIFT
  1272. {
  1273.     my $self = shift;
  1274.     if (@_)
  1275.     {
  1276.         my ($key, $value) = (0, 0) ;
  1277.         my $cursor = $self->db_cursor() ;
  1278.         my $status = $cursor->c_get($key, $value, BerkeleyDB::DB_FIRST()) ;
  1279.         if ($status == 0)
  1280.         {
  1281.             foreach $value (reverse @_)
  1282.             {
  1283.             $key = 0 ;
  1284.             $cursor->c_put($key, $value, BerkeleyDB::DB_BEFORE()) ;
  1285.             }
  1286.         }
  1287.         elsif ($status == BerkeleyDB::DB_NOTFOUND())
  1288.         {
  1289.         $key = 0 ;
  1290.             foreach $value (@_)
  1291.             {
  1292.             $self->db_put($key++, $value) ;
  1293.             }
  1294.         }
  1295.     }
  1296. }
  1297.  
  1298. sub PUSH
  1299. {
  1300.     my $self = shift;
  1301.     if (@_)
  1302.     {
  1303.         my ($key, $value) = (-1, 0) ;
  1304.         my $cursor = $self->db_cursor() ;
  1305.         my $status = $cursor->c_get($key, $value, BerkeleyDB::DB_LAST()) ;
  1306.         if ($status == 0 || $status == BerkeleyDB::DB_NOTFOUND())
  1307.     {
  1308.             $key = -1 if $status != 0 and $self->type != BerkeleyDB::DB_RECNO() ;
  1309.             foreach $value (@_)
  1310.         {
  1311.             ++ $key ;
  1312.             $status = $self->db_put($key, $value) ;
  1313.         }
  1314.     }
  1315.  
  1316. # can use this when DB_APPEND is fixed.
  1317. #        foreach $value (@_)
  1318. #        {
  1319. #        my $status = $cursor->c_put($key, $value, BerkeleyDB::DB_AFTER()) ;
  1320. #print "[$status]\n" ;
  1321. #        }
  1322.     }
  1323. }
  1324.  
  1325. sub POP
  1326. {
  1327.     my $self = shift;
  1328.     my ($key, $value) = (0, 0) ;
  1329.     my $cursor = $self->db_cursor() ;
  1330.     return undef if $cursor->c_get($key, $value, BerkeleyDB::DB_LAST()) != 0 ;
  1331.     return undef if $cursor->c_del() != 0 ;
  1332.  
  1333.     return $value ;
  1334. }
  1335.  
  1336. sub SPLICE
  1337. {
  1338.     my $self = shift;
  1339.     croak "SPLICE is not implemented yet" ;
  1340. }
  1341.  
  1342. *shift = \&SHIFT ;
  1343. *unshift = \&UNSHIFT ;
  1344. *push = \&PUSH ;
  1345. *pop = \&POP ;
  1346. *clear = \&CLEAR ;
  1347. *length = \&FETCHSIZE ;
  1348.  
  1349. sub STORESIZE
  1350. {
  1351.     croak "STORESIZE is not implemented yet" ;
  1352. #print "STORESIZE @_\n" ;
  1353. #    my $self = shift;
  1354. #    my $length = shift ;
  1355. #    my $current_length = $self->FETCHSIZE() ;
  1356. #print "length is $current_length\n";
  1357. #
  1358. #    if ($length < $current_length) {
  1359. #print "Make smaller $length < $current_length\n" ;
  1360. #        my $key ;
  1361. #        for ($key = $current_length - 1 ; $key >= $length ; -- $key)
  1362. #          { $self->db_del($key) }
  1363. #    }
  1364. #    elsif ($length > $current_length) {
  1365. #print "Make larger $length > $current_length\n" ;
  1366. #        $self->db_put($length-1, "") ;
  1367. #    }
  1368. #    else { print "stay the same\n" }
  1369.  
  1370. }
  1371.  
  1372.  
  1373.  
  1374. #sub DESTROY
  1375. #{
  1376. #    my $self = shift ;
  1377. #    print "BerkeleyDB::_tieArray::DESTROY\n" ;
  1378. #}
  1379.  
  1380.  
  1381. package BerkeleyDB::Common ;
  1382.  
  1383.  
  1384. use Carp ;
  1385.  
  1386. sub DESTROY
  1387. {
  1388.     my $self = shift ;
  1389.     $self->_DESTROY() ;
  1390. }
  1391.  
  1392. sub Txn
  1393. {
  1394.     my $self = shift ;
  1395.     my $txn  = shift ;
  1396.     #print "BerkeleyDB::Common::Txn db [$self] txn [$txn]\n" ;
  1397.     if ($txn) {
  1398.         $self->_Txn($txn) ;
  1399.         push @{ $txn }, $self ;
  1400.     }
  1401.     else {
  1402.         $self->_Txn() ;
  1403.     }
  1404.     #print "end BerkeleyDB::Common::Txn \n";
  1405. }
  1406.  
  1407.  
  1408. sub get_dup
  1409. {
  1410.     croak "Usage: \$db->get_dup(key [,flag])\n"
  1411.         unless @_ == 2 or @_ == 3 ;
  1412.  
  1413.     my $db        = shift ;
  1414.     my $key       = shift ;
  1415.     my $flag      = shift ;
  1416.     my $value       = 0 ;
  1417.     my $origkey   = $key ;
  1418.     my $wantarray = wantarray ;
  1419.     my %values      = () ;
  1420.     my @values    = () ;
  1421.     my $counter   = 0 ;
  1422.     my $status    = 0 ;
  1423.     my $cursor    = $db->db_cursor() ;
  1424.  
  1425.     # iterate through the database until either EOF ($status == 0)
  1426.     # or a different key is encountered ($key ne $origkey).
  1427.     for ($status = $cursor->c_get($key, $value, BerkeleyDB::DB_SET()) ;
  1428.      $status == 0 and $key eq $origkey ;
  1429.          $status = $cursor->c_get($key, $value, BerkeleyDB::DB_NEXT()) ) {
  1430.         # save the value or count number of matches
  1431.         if ($wantarray) {
  1432.         if ($flag)
  1433.                 { ++ $values{$value} }
  1434.         else
  1435.                 { push (@values, $value) }
  1436.     }
  1437.         else
  1438.             { ++ $counter }
  1439.      
  1440.     }
  1441.  
  1442.     return ($wantarray ? ($flag ? %values : @values) : $counter) ;
  1443. }
  1444.  
  1445. sub db_cursor
  1446. {
  1447.     my $db = shift ;
  1448.     my ($addr) = $db->_db_cursor(@_) ;
  1449.     my $obj ;
  1450.     $obj = bless [$addr, $db] , "BerkeleyDB::Cursor" if $addr ;
  1451.     return $obj ;
  1452. }
  1453.  
  1454. sub _db_write_cursor
  1455. {
  1456.     my $db = shift ;
  1457.     my ($addr) = $db->__db_write_cursor(@_) ;
  1458.     my $obj ;
  1459.     $obj = bless [$addr, $db] , "BerkeleyDB::Cursor" if $addr ;
  1460.     return $obj ;
  1461. }
  1462.  
  1463. sub db_join
  1464. {
  1465.     croak 'Usage: $db->BerkeleyDB::db_join([cursors], flags=0)'
  1466.     if @_ < 2 || @_ > 3 ;
  1467.     my $db = shift ;
  1468.     croak 'db_join: first parameter is not an array reference'
  1469.     if ! ref $_[0] || ref $_[0] ne 'ARRAY';
  1470.     my ($addr) = $db->_db_join(@_) ;
  1471.     my $obj ;
  1472.     $obj = bless [$addr, $db, $_[0]] , "BerkeleyDB::Cursor" if $addr ;
  1473.     return $obj ;
  1474. }
  1475.  
  1476. package BerkeleyDB::Cursor ;
  1477.  
  1478. sub c_close
  1479. {
  1480.     my $cursor = shift ;
  1481.     $cursor->[1] = "" ;
  1482.     return $cursor->_c_close() ;
  1483. }
  1484.  
  1485. sub c_dup
  1486. {
  1487.     my $cursor = shift ;
  1488.     my ($addr) = $cursor->_c_dup(@_) ;
  1489.     my $obj ;
  1490.     $obj = bless [$addr, $cursor->[1]] , "BerkeleyDB::Cursor" if $addr ;
  1491.     return $obj ;
  1492. }
  1493.  
  1494. sub DESTROY
  1495. {
  1496.     my $self = shift ;
  1497.     $self->_DESTROY() ;
  1498. }
  1499.  
  1500. package BerkeleyDB::TxnMgr ;
  1501.  
  1502. sub DESTROY
  1503. {
  1504.     my $self = shift ;
  1505.     $self->_DESTROY() ;
  1506. }
  1507.  
  1508. sub txn_begin
  1509. {
  1510.     my $txnmgr = shift ;
  1511.     my ($addr) = $txnmgr->_txn_begin(@_) ;
  1512.     my $obj ;
  1513.     $obj = bless [$addr, $txnmgr] , "BerkeleyDB::Txn" if $addr ;
  1514.     return $obj ;
  1515. }
  1516.  
  1517. package BerkeleyDB::Txn ;
  1518.  
  1519. sub Txn
  1520. {
  1521.     my $self = shift ;
  1522.     my $db ;
  1523.     # keep a reference to each db in the txn object
  1524.     foreach $db (@_) {
  1525.         $db->_Txn($self) ;
  1526.     push @{ $self}, $db ;
  1527.     }
  1528. }
  1529.  
  1530. sub txn_commit
  1531. {
  1532.     my $self = shift ;
  1533.     $self->disassociate() ;
  1534.     my $status = $self->_txn_commit() ;
  1535.     return $status ;
  1536. }
  1537.  
  1538. sub txn_abort
  1539. {
  1540.     my $self = shift ;
  1541.     $self->disassociate() ;
  1542.     my $status = $self->_txn_abort() ;
  1543.     return $status ;
  1544. }
  1545.  
  1546. sub disassociate
  1547. {
  1548.     my $self = shift ;
  1549.     my $db ;
  1550.     while ( @{ $self } > 2) {
  1551.         $db = pop @{ $self } ;
  1552.         $db->Txn() ;
  1553.     }
  1554.     #print "end disassociate\n" ;
  1555. }
  1556.  
  1557.  
  1558. sub DESTROY
  1559. {
  1560.     my $self = shift ;
  1561.  
  1562.     $self->disassociate() ;
  1563.     # first close the close the transaction
  1564.     $self->_DESTROY() ;
  1565. }
  1566.  
  1567.  
  1568. package BerkeleyDB::Term ;
  1569.  
  1570. END
  1571. {
  1572.     close_everything() ;
  1573. }
  1574.  
  1575.  
  1576. package BerkeleyDB ;
  1577.  
  1578.  
  1579.  
  1580. # Autoload methods go after =cut, and are processed by the autosplit program.
  1581.  
  1582. 1;
  1583. __END__
  1584.  
  1585.  
  1586.