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

MySQL数据库

开发平台:

Visual C++

  1. package BerkeleyDB;
  2. #     Copyright (c) 1997-2001 Paul Marquess. All rights reserved.
  3. #     This program is free software; you can redistribute it and/or
  4. #     modify it under the same terms as Perl itself.
  5. #
  6. # The documentation for this module is at the bottom of this file,
  7. # after the line __END__.
  8. BEGIN { require 5.004_04 }
  9. use strict;
  10. use Carp;
  11. use vars qw($VERSION @ISA @EXPORT $AUTOLOAD);
  12. $VERSION = '0.13';
  13. require Exporter;
  14. require DynaLoader;
  15. require AutoLoader;
  16. use IO ;
  17. @ISA = qw(Exporter DynaLoader);
  18. # Items to export into callers namespace by default. Note: do not export
  19. # names by default without a very good reason. Use EXPORT_OK instead.
  20. # Do not simply export all your public functions/methods/constants.
  21. @EXPORT = qw(
  22. DB_AFTER
  23. DB_APPEND
  24. DB_ARCH_ABS
  25. DB_ARCH_DATA
  26. DB_ARCH_LOG
  27. DB_BEFORE
  28. DB_BTREE
  29. DB_BTREEMAGIC
  30. DB_BTREEOLDVER
  31. DB_BTREEVERSION
  32. DB_CHECKPOINT
  33. DB_CONSUME
  34. DB_CREATE
  35. DB_CURLSN
  36. DB_CURRENT
  37. DB_DBT_MALLOC
  38. DB_DBT_PARTIAL
  39. DB_DBT_USERMEM
  40. DB_DELETED
  41. DB_DELIMITER
  42. DB_DUP
  43. DB_DUPSORT
  44. DB_ENV_APPINIT
  45. DB_ENV_STANDALONE
  46. DB_ENV_THREAD
  47. DB_EXCL
  48. DB_FILE_ID_LEN
  49. DB_FIRST
  50. DB_FIXEDLEN
  51. DB_FLUSH
  52. DB_FORCE
  53. DB_GET_BOTH
  54. DB_GET_RECNO
  55. DB_HASH
  56. DB_HASHMAGIC
  57. DB_HASHOLDVER
  58. DB_HASHVERSION
  59. DB_INCOMPLETE
  60. DB_INIT_CDB
  61. DB_INIT_LOCK
  62. DB_INIT_LOG
  63. DB_INIT_MPOOL
  64. DB_INIT_TXN
  65. DB_JOIN_ITEM
  66. DB_KEYEMPTY
  67. DB_KEYEXIST
  68. DB_KEYFIRST
  69. DB_KEYLAST
  70. DB_LAST
  71. DB_LOCKMAGIC
  72. DB_LOCKVERSION
  73. DB_LOCK_CONFLICT
  74. DB_LOCK_DEADLOCK
  75. DB_LOCK_DEFAULT
  76. DB_LOCK_GET
  77. DB_LOCK_NORUN
  78. DB_LOCK_NOTGRANTED
  79. DB_LOCK_NOTHELD
  80. DB_LOCK_NOWAIT
  81. DB_LOCK_OLDEST
  82. DB_LOCK_RANDOM
  83. DB_LOCK_RIW_N
  84. DB_LOCK_RW_N
  85. DB_LOCK_YOUNGEST
  86. DB_LOGMAGIC
  87. DB_LOGOLDVER
  88. DB_MAX_PAGES
  89. DB_MAX_RECORDS
  90. DB_MPOOL_CLEAN
  91. DB_MPOOL_CREATE
  92. DB_MPOOL_DIRTY
  93. DB_MPOOL_DISCARD
  94. DB_MPOOL_LAST
  95. DB_MPOOL_NEW
  96. DB_MPOOL_PRIVATE
  97. DB_MUTEXDEBUG
  98. DB_MUTEXLOCKS
  99. DB_NEEDSPLIT
  100. DB_NEXT
  101. DB_NEXT_DUP
  102. DB_NOMMAP
  103. DB_NOOVERWRITE
  104. DB_NOSYNC
  105. DB_NOTFOUND
  106. DB_PAD
  107. DB_PAGEYIELD
  108. DB_POSITION
  109. DB_PREV
  110. DB_PRIVATE
  111. DB_QUEUE
  112. DB_RDONLY
  113. DB_RECNO
  114. DB_RECNUM
  115. DB_RECORDCOUNT
  116. DB_RECOVER
  117. DB_RECOVER_FATAL
  118. DB_REGISTERED
  119. DB_RENUMBER
  120. DB_RMW
  121. DB_RUNRECOVERY
  122. DB_SEQUENTIAL
  123. DB_SET
  124. DB_SET_RANGE
  125. DB_SET_RECNO
  126. DB_SNAPSHOT
  127. DB_SWAPBYTES
  128. DB_TEMPORARY
  129. DB_THREAD
  130. DB_TRUNCATE
  131. DB_TXNMAGIC
  132. DB_TXNVERSION
  133. DB_TXN_BACKWARD_ROLL
  134. DB_TXN_CKP
  135. DB_TXN_FORWARD_ROLL
  136. DB_TXN_LOCK_2PL
  137. DB_TXN_LOCK_MASK
  138. DB_TXN_LOCK_OPTIMIST
  139. DB_TXN_LOCK_OPTIMISTIC
  140. DB_TXN_LOG_MASK
  141. DB_TXN_LOG_REDO
  142. DB_TXN_LOG_UNDO
  143. DB_TXN_LOG_UNDOREDO
  144. DB_TXN_NOSYNC
  145. DB_TXN_NOWAIT
  146. DB_TXN_OPENFILES
  147. DB_TXN_REDO
  148. DB_TXN_SYNC
  149. DB_TXN_UNDO
  150. DB_USE_ENVIRON
  151. DB_USE_ENVIRON_ROOT
  152. DB_VERSION_MAJOR
  153. DB_VERSION_MINOR
  154. DB_VERSION_PATCH
  155. DB_WRITECURSOR
  156. );
  157. sub AUTOLOAD {
  158.     # This AUTOLOAD is used to 'autoload' constants from the constant()
  159.     # XS function.  If a constant is not found then control is passed
  160.     # to the AUTOLOAD in AutoLoader.
  161.     my $constname;
  162.     ($constname = $AUTOLOAD) =~ s/.*:://;
  163.     my $val = constant($constname, @_ ? $_[0] : 0);
  164.     if ($! != 0) {
  165. if ($! =~ /Invalid/) {
  166.     $AutoLoader::AUTOLOAD = $AUTOLOAD;
  167.     goto &AutoLoader::AUTOLOAD;
  168. }
  169. else {
  170. croak "Your vendor has not defined BerkeleyDB macro $constname";
  171. }
  172.     }
  173.     eval "sub $AUTOLOAD { $val }";
  174.     goto &$AUTOLOAD;
  175. }
  176. bootstrap BerkeleyDB $VERSION;
  177. # Preloaded methods go here.
  178. sub ParseParameters($@)
  179. {
  180.     my ($default, @rest) = @_ ;
  181.     my (%got) = %$default ;
  182.     my (@Bad) ;
  183.     my ($key, $value) ;
  184.     my $sub = (caller(1))[3] ;
  185.     my %options = () ;
  186.     local ($Carp::CarpLevel) = 1 ;
  187.     # allow the options to be passed as a hash reference or
  188.     # as the complete hash.
  189.     if (@rest == 1) {
  190.         croak "$sub: parameter is not a reference to a hash"
  191.             if ref $rest[0] ne "HASH" ;
  192.         %options = %{ $rest[0] } ;
  193.     }
  194.     elsif (@rest >= 2) {
  195.         %options = @rest ;
  196.     }
  197.     while (($key, $value) = each %options)
  198.     {
  199. $key =~ s/^-// ;
  200.         if (exists $default->{$key})
  201.           { $got{$key} = $value }
  202.         else
  203.   { push (@Bad, $key) }
  204.     }
  205.     
  206.     if (@Bad) {
  207.         my ($bad) = join(", ", @Bad) ;
  208.         croak "unknown key value(s) @Bad" ;
  209.     }
  210.     return %got ;
  211. }
  212. use UNIVERSAL qw( isa ) ;
  213. sub env_remove
  214. {
  215.     # Usage:
  216.     #
  217.     # $env = new BerkeleyDB::Env
  218.     # [ -Home => $path, ]
  219.     # [ -Config => { name => value, name => value }
  220.     # [ -Flags => DB_INIT_LOCK| ]
  221.     # ;
  222.     my $got = BerkeleyDB::ParseParameters({
  223. Home => undef,
  224. Flags      => 0,
  225. Config => undef,
  226. }, @_) ;
  227.     if (defined $got->{ErrFile}) {
  228. if (!isaFilehandle($got->{ErrFile})) {
  229.     my $handle = new IO::File ">$got->{ErrFile}"
  230. or croak "Cannot open file $got->{ErrFile}: $!n" ;
  231.     $got->{ErrFile} = $handle ;
  232. }
  233.     }
  234.     
  235.     if (defined $got->{Config}) {
  236.      croak("Config parameter must be a hash reference")
  237.             if ! ref $got->{Config} eq 'HASH' ;
  238.         @BerkeleyDB::a = () ;
  239. my $k = "" ; my $v = "" ;
  240. while (($k, $v) = each %{$got->{Config}}) {
  241.     push @BerkeleyDB::a, "$kt$v" ;
  242. }
  243.         $got->{"Config"} = pack("p*", @BerkeleyDB::a, undef) 
  244.     if @BerkeleyDB::a ;
  245.     }
  246.     return _env_remove($got) ;
  247. }
  248. sub db_remove
  249. {
  250.     my $got = BerkeleyDB::ParseParameters(
  251.       {
  252. Filename  => undef,
  253. Subname => undef,
  254. Flags => 0,
  255. Env => undef,
  256.       }, @_) ;
  257.     croak("Must specify a filename")
  258. if ! defined $got->{Filename} ;
  259.     croak("Env not of type BerkeleyDB::Env")
  260. if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  261.     return _db_remove($got);
  262. }
  263. package BerkeleyDB::Env ;
  264. use UNIVERSAL qw( isa ) ;
  265. use Carp ;
  266. use vars qw( %valid_config_keys ) ;
  267. sub isaFilehandle
  268. {
  269.     my $fh = shift ;
  270.     return ((isa($fh,'GLOB') or isa($fh,'GLOB')) and defined fileno($fh) )
  271. }
  272. %valid_config_keys = map { $_, 1 } qw( DB_DATA_DIR DB_LOG_DIR DB_TEMP_DIR ) ;
  273. sub new
  274. {
  275.     # Usage:
  276.     #
  277.     # $env = new BerkeleyDB::Env
  278.     # [ -Home => $path, ]
  279.     # [ -Mode => mode, ]
  280.     # [ -Config => { name => value, name => value }
  281.     # [ -ErrFile    => filename or filehandle, ]
  282.     # [ -ErrPrefix  => "string", ]
  283.     # [ -Flags => DB_INIT_LOCK| ]
  284.     # [ -Cachesize => number ]
  285.     # [ -LockDetect =>  ]
  286.     # [ -Verbose => boolean ]
  287.     # ;
  288.     my $pkg = shift ;
  289.     my $got = BerkeleyDB::ParseParameters({
  290. Home => undef,
  291. Server => undef,
  292. Mode => 0666,
  293. ErrFile   => undef,
  294. ErrPrefix  => undef,
  295. Flags      => 0,
  296. Cachesize      => 0,
  297. LockDetect      => 0,
  298. Verbose => 0,
  299. Config => undef,
  300. }, @_) ;
  301.     if (defined $got->{ErrFile}) {
  302. if (!isaFilehandle($got->{ErrFile})) {
  303.     my $handle = new IO::File ">$got->{ErrFile}"
  304. or croak "Cannot open file $got->{ErrFile}: $!n" ;
  305.     $got->{ErrFile} = $handle ;
  306. }
  307.     }
  308.     
  309.     my %config ;
  310.     if (defined $got->{Config}) {
  311.      croak("Config parameter must be a hash reference")
  312.             if ! ref $got->{Config} eq 'HASH' ;
  313. %config = %{ $got->{Config} } ;
  314.         @BerkeleyDB::a = () ;
  315. my $k = "" ; my $v = "" ;
  316. while (($k, $v) = each %config) {
  317.     if ($BerkeleyDB::db_version >= 3.1 && ! $valid_config_keys{$k} ) {
  318.         $BerkeleyDB::Error = "illegal name-value pair: $k $vn" ; 
  319.                 croak $BerkeleyDB::Error ;
  320.     }
  321.     push @BerkeleyDB::a, "$kt$v" ;
  322. }
  323.         $got->{"Config"} = pack("p*", @BerkeleyDB::a, undef) 
  324.     if @BerkeleyDB::a ;
  325.     }
  326.     my ($addr) = _db_appinit($pkg, $got) ;
  327.     my $obj ;
  328.     $obj = bless [$addr] , $pkg if $addr ;
  329.     if ($obj && $BerkeleyDB::db_version >= 3.1 && keys %config) {
  330. my ($k, $v);
  331. while (($k, $v) = each %config) {
  332.     if ($k eq 'DB_DATA_DIR')
  333.       { $obj->set_data_dir($v) }
  334.     elsif ($k eq 'DB_LOG_DIR')
  335.       { $obj->set_lg_dir($v) }
  336.     elsif ($k eq 'DB_TEMP_DIR')
  337.       { $obj->set_tmp_dir($v) }
  338.     else {
  339.       $BerkeleyDB::Error = "illegal name-value pair: $k $vn" ; 
  340.               croak $BerkeleyDB::Error 
  341.             }
  342. }
  343.     }
  344.     return $obj ;
  345. }
  346. sub TxnMgr
  347. {
  348.     my $env = shift ;
  349.     my ($addr) = $env->_TxnMgr() ;
  350.     my $obj ;
  351.     $obj = bless [$addr, $env] , "BerkeleyDB::TxnMgr" if $addr ;
  352.     return $obj ;
  353. }
  354. sub txn_begin
  355. {
  356.     my $env = shift ;
  357.     my ($addr) = $env->_txn_begin(@_) ;
  358.     my $obj ;
  359.     $obj = bless [$addr, $env] , "BerkeleyDB::Txn" if $addr ;
  360.     return $obj ;
  361. }
  362. sub DESTROY
  363. {
  364.     my $self = shift ;
  365.     $self->_DESTROY() ;
  366. }
  367. package BerkeleyDB::Hash ;
  368. use vars qw(@ISA) ;
  369. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedHash ) ;
  370. use UNIVERSAL qw( isa ) ;
  371. use Carp ;
  372. sub new
  373. {
  374.     my $self = shift ;
  375.     my $got = BerkeleyDB::ParseParameters(
  376.       {
  377. # Generic Stuff
  378. Filename  => undef,
  379. Subname => undef,
  380. #Flags => BerkeleyDB::DB_CREATE(),
  381. Flags => 0,
  382. Property => 0,
  383. Mode => 0666,
  384. Cachesize  => 0,
  385. Lorder  => 0,
  386. Pagesize  => 0,
  387. Env => undef,
  388. #Tie  => undef,
  389. Txn => undef,
  390. # Hash specific
  391. Ffactor => 0,
  392. Nelem  => 0,
  393. Hash  => undef,
  394. DupCompare => undef,
  395. # BerkeleyDB specific
  396. ReadKey => undef,
  397. WriteKey => undef,
  398. ReadValue => undef,
  399. WriteValue => undef,
  400.       }, @_) ;
  401.     croak("Env not of type BerkeleyDB::Env")
  402. if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  403.     croak("Txn not of type BerkeleyDB::Txn")
  404. if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  405.     croak("-Tie needs a reference to a hash")
  406. if defined $got->{Tie} and $got->{Tie} !~ /HASH/ ;
  407.     my ($addr) = _db_open_hash($self, $got);
  408.     my $obj ;
  409.     if ($addr) {
  410.         $obj = bless [$addr] , $self ;
  411. push @{ $obj }, $got->{Env} if $got->{Env} ;
  412.         $obj->Txn($got->{Txn}) if $got->{Txn} ;
  413.     }
  414.     return $obj ;
  415. }
  416. *TIEHASH = &new ;
  417.  
  418. package BerkeleyDB::Btree ;
  419. use vars qw(@ISA) ;
  420. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedHash ) ;
  421. use UNIVERSAL qw( isa ) ;
  422. use Carp ;
  423. sub new
  424. {
  425.     my $self = shift ;
  426.     my $got = BerkeleyDB::ParseParameters(
  427.       {
  428. # Generic Stuff
  429. Filename  => undef,
  430. Subname => undef,
  431. #Flags => BerkeleyDB::DB_CREATE(),
  432. Flags => 0,
  433. Property => 0,
  434. Mode => 0666,
  435. Cachesize  => 0,
  436. Lorder  => 0,
  437. Pagesize  => 0,
  438. Env => undef,
  439. #Tie  => undef,
  440. Txn => undef,
  441. # Btree specific
  442. Minkey => 0,
  443. Compare => undef,
  444. DupCompare => undef,
  445. Prefix  => undef,
  446.       }, @_) ;
  447.     croak("Env not of type BerkeleyDB::Env")
  448. if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  449.     croak("Txn not of type BerkeleyDB::Txn")
  450. if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  451.     croak("-Tie needs a reference to a hash")
  452. if defined $got->{Tie} and $got->{Tie} !~ /HASH/ ;
  453.     my ($addr) = _db_open_btree($self, $got);
  454.     my $obj ;
  455.     if ($addr) {
  456.         $obj = bless [$addr] , $self ;
  457. push @{ $obj }, $got->{Env} if $got->{Env} ;
  458.         $obj->Txn($got->{Txn}) if $got->{Txn} ;
  459.     }
  460.     return $obj ;
  461. }
  462. *BerkeleyDB::Btree::TIEHASH = &BerkeleyDB::Btree::new ;
  463. package BerkeleyDB::Recno ;
  464. use vars qw(@ISA) ;
  465. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
  466. use UNIVERSAL qw( isa ) ;
  467. use Carp ;
  468. sub new
  469. {
  470.     my $self = shift ;
  471.     my $got = BerkeleyDB::ParseParameters(
  472.       {
  473. # Generic Stuff
  474. Filename  => undef,
  475. Subname => undef,
  476. #Flags => BerkeleyDB::DB_CREATE(),
  477. Flags => 0,
  478. Property => 0,
  479. Mode => 0666,
  480. Cachesize  => 0,
  481. Lorder  => 0,
  482. Pagesize  => 0,
  483. Env => undef,
  484. #Tie  => undef,
  485. Txn => undef,
  486. # Recno specific
  487. Delim => undef,
  488. Len => undef,
  489. Pad => undef,
  490. Source  => undef,
  491. ArrayBase  => 1, # lowest index in array
  492.       }, @_) ;
  493.     croak("Env not of type BerkeleyDB::Env")
  494. if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  495.     croak("Txn not of type BerkeleyDB::Txn")
  496. if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  497.     croak("Tie needs a reference to an array")
  498. if defined $got->{Tie} and $got->{Tie} !~ /ARRAY/ ;
  499.     croak("ArrayBase can only be 0 or 1, parsed $got->{ArrayBase}")
  500. if $got->{ArrayBase} != 1 and $got->{ArrayBase} != 0 ;
  501.     $got->{Fname} = $got->{Filename} if defined $got->{Filename} ;
  502.     my ($addr) = _db_open_recno($self, $got);
  503.     my $obj ;
  504.     if ($addr) {
  505.         $obj = bless [$addr] , $self ;
  506. push @{ $obj }, $got->{Env} if $got->{Env} ;
  507.         $obj->Txn($got->{Txn}) if $got->{Txn} ;
  508.     }
  509.     return $obj ;
  510. }
  511. *BerkeleyDB::Recno::TIEARRAY = &BerkeleyDB::Recno::new ;
  512. *BerkeleyDB::Recno::db_stat = &BerkeleyDB::Btree::db_stat ;
  513. package BerkeleyDB::Queue ;
  514. use vars qw(@ISA) ;
  515. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
  516. use UNIVERSAL qw( isa ) ;
  517. use Carp ;
  518. sub new
  519. {
  520.     my $self = shift ;
  521.     my $got = BerkeleyDB::ParseParameters(
  522.       {
  523. # Generic Stuff
  524. Filename  => undef,
  525. Subname => undef,
  526. #Flags => BerkeleyDB::DB_CREATE(),
  527. Flags => 0,
  528. Property => 0,
  529. Mode => 0666,
  530. Cachesize  => 0,
  531. Lorder  => 0,
  532. Pagesize  => 0,
  533. Env => undef,
  534. #Tie  => undef,
  535. Txn => undef,
  536. # Queue specific
  537. Len => undef,
  538. Pad => undef,
  539. ArrayBase  => 1, # lowest index in array
  540. ExtentSize      => undef,
  541.       }, @_) ;
  542.     croak("Env not of type BerkeleyDB::Env")
  543. if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  544.     croak("Txn not of type BerkeleyDB::Txn")
  545. if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  546.     croak("Tie needs a reference to an array")
  547. if defined $got->{Tie} and $got->{Tie} !~ /ARRAY/ ;
  548.     croak("ArrayBase can only be 0 or 1, parsed $got->{ArrayBase}")
  549. if $got->{ArrayBase} != 1 and $got->{ArrayBase} != 0 ;
  550.     my ($addr) = _db_open_queue($self, $got);
  551.     my $obj ;
  552.     if ($addr) {
  553.         $obj = bless [$addr] , $self ;
  554. push @{ $obj }, $got->{Env} if $got->{Env} ;
  555.         $obj->Txn($got->{Txn}) if $got->{Txn} ;
  556.     }
  557.     return $obj ;
  558. }
  559. *BerkeleyDB::Queue::TIEARRAY = &BerkeleyDB::Queue::new ;
  560. ## package BerkeleyDB::Text ;
  561. ## 
  562. ## use vars qw(@ISA) ;
  563. ## @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
  564. ## use UNIVERSAL qw( isa ) ;
  565. ## use Carp ;
  566. ## 
  567. ## sub new
  568. ## {
  569. ##     my $self = shift ;
  570. ##     my $got = BerkeleyDB::ParseParameters(
  571. ##        {
  572. ##  # Generic Stuff
  573. ##  Filename  => undef,
  574. ##  #Flags => BerkeleyDB::DB_CREATE(),
  575. ##  Flags => 0,
  576. ##  Property => 0,
  577. ##  Mode => 0666,
  578. ##  Cachesize  => 0,
  579. ##  Lorder  => 0,
  580. ##  Pagesize  => 0,
  581. ##  Env => undef,
  582. ##  #Tie  => undef,
  583. ##  Txn => undef,
  584. ## 
  585. ##  # Recno specific
  586. ##  Delim => undef,
  587. ##  Len => undef,
  588. ##  Pad => undef,
  589. ##  Btree  => undef,
  590. ##        }, @_) ;
  591. ## 
  592. ##     croak("Env not of type BerkeleyDB::Env")
  593. ##  if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  594. ## 
  595. ##     croak("Txn not of type BerkeleyDB::Txn")
  596. ##  if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  597. ## 
  598. ##     croak("-Tie needs a reference to an array")
  599. ##  if defined $got->{Tie} and $got->{Tie} !~ /ARRAY/ ;
  600. ## 
  601. ##     # rearange for recno
  602. ##     $got->{Source} = $got->{Filename} if defined $got->{Filename} ;
  603. ##     delete $got->{Filename} ;
  604. ##     $got->{Fname} = $got->{Btree} if defined $got->{Btree} ;
  605. ##     return BerkeleyDB::Recno::_db_open_recno($self, $got);
  606. ## }
  607. ## 
  608. ## *BerkeleyDB::Text::TIEARRAY = &BerkeleyDB::Text::new ;
  609. ## *BerkeleyDB::Text::db_stat = &BerkeleyDB::Btree::db_stat ;
  610. package BerkeleyDB::Unknown ;
  611. use vars qw(@ISA) ;
  612. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
  613. use UNIVERSAL qw( isa ) ;
  614. use Carp ;
  615. sub new
  616. {
  617.     my $self = shift ;
  618.     my $got = BerkeleyDB::ParseParameters(
  619.       {
  620. # Generic Stuff
  621. Filename  => undef,
  622. Subname => undef,
  623. #Flags => BerkeleyDB::DB_CREATE(),
  624. Flags => 0,
  625. Property => 0,
  626. Mode => 0666,
  627. Cachesize  => 0,
  628. Lorder  => 0,
  629. Pagesize  => 0,
  630. Env => undef,
  631. #Tie  => undef,
  632. Txn => undef,
  633.       }, @_) ;
  634.     croak("Env not of type BerkeleyDB::Env")
  635. if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  636.     croak("Txn not of type BerkeleyDB::Txn")
  637. if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  638.     croak("-Tie needs a reference to a hash")
  639. if defined $got->{Tie} and $got->{Tie} !~ /HASH/ ;
  640.     my ($addr, $type) = _db_open_unknown($got);
  641.     my $obj ;
  642.     if ($addr) {
  643.         $obj = bless [$addr], "BerkeleyDB::$type" ;
  644. push @{ $obj }, $got->{Env} if $got->{Env} ;
  645.         $obj->Txn($got->{Txn}) if $got->{Txn} ;
  646.     }
  647.     return $obj ;
  648. }
  649. package BerkeleyDB::_tiedHash ;
  650. use Carp ;
  651. #sub TIEHASH  
  652. #{ 
  653. #    my $self = shift ;
  654. #    my $db_object = shift ;
  655. #
  656. #print "Tiehash REF=[$self] [" . (ref $self) . "]n" ;
  657. #
  658. #    return bless { Obj => $db_object}, $self ; 
  659. #}
  660. sub Tie
  661. {
  662.     # Usage:
  663.     #
  664.     #   $db->Tie %hash ;
  665.     #
  666.     my $self = shift ;
  667.     #print "Tie method REF=[$self] [" . (ref $self) . "]n" ;
  668.     croak("usage $x->Tie \%hashn") unless @_ ;
  669.     my $ref  = shift ; 
  670.     croak("Tie needs a reference to a hash")
  671. if defined $ref and $ref !~ /HASH/ ;
  672.     #tie %{ $ref }, ref($self), $self ; 
  673.     tie %{ $ref }, "BerkeleyDB::_tiedHash", $self ; 
  674.     return undef ;
  675. }
  676.  
  677. sub TIEHASH  
  678.     my $self = shift ;
  679.     my $db_object = shift ;
  680.     #return bless $db_object, 'BerkeleyDB::Common' ; 
  681.     return $db_object ;
  682. }
  683. sub STORE
  684. {
  685.     my $self = shift ;
  686.     my $key  = shift ;
  687.     my $value = shift ;
  688.     $self->db_put($key, $value) ;
  689. }
  690. sub FETCH
  691. {
  692.     my $self = shift ;
  693.     my $key  = shift ;
  694.     my $value = undef ;
  695.     $self->db_get($key, $value) ;
  696.     return $value ;
  697. }
  698. sub EXISTS
  699. {
  700.     my $self = shift ;
  701.     my $key  = shift ;
  702.     my $value = undef ;
  703.     $self->db_get($key, $value) == 0 ;
  704. }
  705. sub DELETE
  706. {
  707.     my $self = shift ;
  708.     my $key  = shift ;
  709.     $self->db_del($key) ;
  710. }
  711. sub CLEAR
  712. {
  713.     my $self = shift ;
  714.     my ($key, $value) = (0, 0) ;
  715.     my $cursor = $self->db_cursor() ;
  716.     while ($cursor->c_get($key, $value, BerkeleyDB::DB_PREV()) == 0) 
  717. { $cursor->c_del() }
  718.     #1 while $cursor->c_del() == 0 ;
  719.     # cursor will self-destruct
  720. }
  721. #sub DESTROY
  722. #{
  723. #    my $self = shift ;
  724. #    print "BerkeleyDB::_tieHash::DESTROYn" ;
  725. #    $self->{Cursor}->c_close() if $self->{Cursor} ;
  726. #}
  727. package BerkeleyDB::_tiedArray ;
  728. use Carp ;
  729. sub Tie
  730. {
  731.     # Usage:
  732.     #
  733.     #   $db->Tie @array ;
  734.     #
  735.     my $self = shift ;
  736.     #print "Tie method REF=[$self] [" . (ref $self) . "]n" ;
  737.     croak("usage $x->Tie \%hashn") unless @_ ;
  738.     my $ref  = shift ; 
  739.     croak("Tie needs a reference to an array")
  740. if defined $ref and $ref !~ /ARRAY/ ;
  741.     #tie %{ $ref }, ref($self), $self ; 
  742.     tie @{ $ref }, "BerkeleyDB::_tiedArray", $self ; 
  743.     return undef ;
  744. }
  745.  
  746. #sub TIEARRAY  
  747. #{ 
  748. #    my $self = shift ;
  749. #    my $db_object = shift ;
  750. #
  751. #print "Tiearray REF=[$self] [" . (ref $self) . "]n" ;
  752. #
  753. #    return bless { Obj => $db_object}, $self ; 
  754. #}
  755. sub TIEARRAY  
  756.     my $self = shift ;
  757.     my $db_object = shift ;
  758.     #return bless $db_object, 'BerkeleyDB::Common' ; 
  759.     return $db_object ;
  760. }
  761. sub STORE
  762. {
  763.     my $self = shift ;
  764.     my $key  = shift ;
  765.     my $value = shift ;
  766.     $self->db_put($key, $value) ;
  767. }
  768. sub FETCH
  769. {
  770.     my $self = shift ;
  771.     my $key  = shift ;
  772.     my $value = undef ;
  773.     $self->db_get($key, $value) ;
  774.     return $value ;
  775. }
  776. *CLEAR =    &BerkeleyDB::_tiedHash::CLEAR ;
  777. *FIRSTKEY = &BerkeleyDB::_tiedHash::FIRSTKEY ;
  778. *NEXTKEY =  &BerkeleyDB::_tiedHash::NEXTKEY ;
  779. sub EXTEND {} # don't do anything with EXTEND
  780. sub SHIFT
  781. {
  782.     my $self = shift;
  783.     my ($key, $value) = (0, 0) ;
  784.     my $cursor = $self->db_cursor() ;
  785.     return undef if $cursor->c_get($key, $value, BerkeleyDB::DB_FIRST()) != 0 ;
  786.     return undef if $cursor->c_del() != 0 ;
  787.     return $value ;
  788. }
  789. sub UNSHIFT
  790. {
  791.     my $self = shift;
  792.     croak "unshift is unsupported with Queue databases"
  793.         if $self->type == BerkeleyDB::DB_QUEUE() ;
  794.     if (@_)
  795.     {
  796.         my ($key, $value) = (0, 0) ;
  797.         my $cursor = $self->db_cursor() ;
  798.         if ($cursor->c_get($key, $value, BerkeleyDB::DB_FIRST()) == 0) 
  799.         {
  800.             foreach $value (reverse @_)
  801.             {
  802.         $key = 0 ;
  803.         $cursor->c_put($key, $value, BerkeleyDB::DB_BEFORE()) ;
  804.             }
  805.         }
  806.     }
  807. }
  808. sub PUSH
  809. {
  810.     my $self = shift;
  811.     if (@_)
  812.     {
  813.         my ($key, $value) = (0, 0) ;
  814.         my $cursor = $self->db_cursor() ;
  815.         if ($cursor->c_get($key, $value, BerkeleyDB::DB_LAST()) == 0)
  816. {
  817.             foreach $value (@_)
  818.     {
  819.         ++ $key ;
  820.         $self->db_put($key, $value) ;
  821.     }
  822. }
  823. # can use this when DB_APPEND is fixed.
  824. #        foreach $value (@_)
  825. #        {
  826. #     my $status = $cursor->c_put($key, $value, BerkeleyDB::DB_AFTER()) ;
  827. #print "[$status]n" ;
  828. #        }
  829.     }
  830. }
  831. sub POP
  832. {
  833.     my $self = shift;
  834.     my ($key, $value) = (0, 0) ;
  835.     my $cursor = $self->db_cursor() ;
  836.     return undef if $cursor->c_get($key, $value, BerkeleyDB::DB_LAST()) != 0 ;
  837.     return undef if $cursor->c_del() != 0 ;
  838.     return $value ;
  839. }
  840. sub SPLICE
  841. {
  842.     my $self = shift;
  843.     croak "SPLICE is not implemented yet" ;
  844. }
  845. *shift = &SHIFT ;
  846. *unshift = &UNSHIFT ;
  847. *push = &PUSH ;
  848. *pop = &POP ;
  849. *clear = &CLEAR ;
  850. *length = &FETCHSIZE ;
  851. sub STORESIZE
  852. {
  853.     croak "STORESIZE is not implemented yet" ;
  854. #print "STORESIZE @_n" ;
  855. #    my $self = shift;
  856. #    my $length = shift ;
  857. #    my $current_length = $self->FETCHSIZE() ;
  858. #print "length is $current_lengthn";
  859. #
  860. #    if ($length < $current_length) {
  861. #print "Make smaller $length < $current_lengthn" ;
  862. #        my $key ;
  863. #        for ($key = $current_length - 1 ; $key >= $length ; -- $key)
  864. #          { $self->db_del($key) }
  865. #    }
  866. #    elsif ($length > $current_length) {
  867. #print "Make larger $length > $current_lengthn" ;
  868. #        $self->db_put($length-1, "") ;
  869. #    }
  870. #    else { print "stay the samen" }
  871. }
  872. #sub DESTROY
  873. #{
  874. #    my $self = shift ;
  875. #    print "BerkeleyDB::_tieArray::DESTROYn" ;
  876. #}
  877. package BerkeleyDB::Common ;
  878. use Carp ;
  879. sub DESTROY
  880. {
  881.     my $self = shift ;
  882.     $self->_DESTROY() ;
  883. }
  884. sub Txn
  885. {
  886.     my $self = shift ;
  887.     my $txn  = shift ;
  888.     #print "BerkeleyDB::Common::Txn db [$self] txn [$txn]n" ;
  889.     if ($txn) {
  890.         $self->_Txn($txn) ;
  891.         push @{ $txn }, $self ;
  892.     }
  893.     else {
  894.         $self->_Txn() ;
  895.     }
  896.     #print "end BerkeleyDB::Common::Txn n";
  897. }
  898. sub get_dup
  899. {
  900.     croak "Usage: $db->get_dup(key [,flag])n"
  901.         unless @_ == 2 or @_ == 3 ;
  902.  
  903.     my $db        = shift ;
  904.     my $key       = shift ;
  905.     my $flag   = shift ;
  906.     my $value    = 0 ;
  907.     my $origkey   = $key ;
  908.     my $wantarray = wantarray ;
  909.     my %values   = () ;
  910.     my @values    = () ;
  911.     my $counter   = 0 ;
  912.     my $status    = 0 ;
  913.     my $cursor    = $db->db_cursor() ;
  914.  
  915.     # iterate through the database until either EOF ($status == 0)
  916.     # or a different key is encountered ($key ne $origkey).
  917.     for ($status = $cursor->c_get($key, $value, BerkeleyDB::DB_SET()) ;
  918.  $status == 0 and $key eq $origkey ;
  919.          $status = $cursor->c_get($key, $value, BerkeleyDB::DB_NEXT()) ) {
  920.         # save the value or count number of matches
  921.         if ($wantarray) {
  922.     if ($flag)
  923.                 { ++ $values{$value} }
  924.     else
  925.                 { push (@values, $value) }
  926. }
  927.         else
  928.             { ++ $counter }
  929.      
  930.     }
  931.  
  932.     return ($wantarray ? ($flag ? %values : @values) : $counter) ;
  933. }
  934. sub db_cursor
  935. {
  936.     my $db = shift ;
  937.     my ($addr) = $db->_db_cursor(@_) ;
  938.     my $obj ;
  939.     $obj = bless [$addr, $db] , "BerkeleyDB::Cursor" if $addr ;
  940.     return $obj ;
  941. }
  942. sub db_join
  943. {
  944.     croak 'Usage: $db->BerkeleyDB::Common::db_join([cursors], flags=0)'
  945. if @_ < 2 || @_ > 3 ;
  946.     my $db = shift ;
  947.     my ($addr) = $db->_db_join(@_) ;
  948.     my $obj ;
  949.     $obj = bless [$addr, $db] , "BerkeleyDB::Cursor" if $addr ;
  950.     return $obj ;
  951. }
  952. package BerkeleyDB::Cursor ;
  953. sub c_close
  954. {
  955.     my $cursor = shift ;
  956.     $cursor->[1] = "" ;
  957.     return $cursor->_c_close() ;
  958. }
  959. sub c_dup
  960. {
  961.     my $cursor = shift ;
  962.     my ($addr) = $cursor->_c_dup(@_) ;
  963.     my $obj ;
  964.     $obj = bless [$addr, $cursor->[1]] , "BerkeleyDB::Cursor" if $addr ;
  965.     return $obj ;
  966. }
  967. sub DESTROY
  968. {
  969.     my $self = shift ;
  970.     $self->_DESTROY() ;
  971. }
  972. package BerkeleyDB::TxnMgr ;
  973. sub DESTROY
  974. {
  975.     my $self = shift ;
  976.     $self->_DESTROY() ;
  977. }
  978. sub txn_begin
  979. {
  980.     my $txnmgr = shift ;
  981.     my ($addr) = $txnmgr->_txn_begin(@_) ;
  982.     my $obj ;
  983.     $obj = bless [$addr, $txnmgr] , "BerkeleyDB::Txn" if $addr ;
  984.     return $obj ;
  985. }
  986. package BerkeleyDB::Txn ;
  987. sub Txn
  988. {
  989.     my $self = shift ;
  990.     my $db ;
  991.     # keep a reference to each db in the txn object
  992.     foreach $db (@_) {
  993.         $db->_Txn($self) ;
  994. push @{ $self}, $db ;
  995.     }
  996. }
  997. sub txn_commit
  998. {
  999.     my $self = shift ;
  1000.     $self->disassociate() ;
  1001.     my $status = $self->_txn_commit() ;
  1002.     return $status ;
  1003. }
  1004. sub txn_abort
  1005. {
  1006.     my $self = shift ;
  1007.     $self->disassociate() ;
  1008.     my $status = $self->_txn_abort() ;
  1009.     return $status ;
  1010. }
  1011. sub disassociate
  1012. {
  1013.     my $self = shift ;
  1014.     my $db ;
  1015.     while ( @{ $self } > 2) {
  1016.         $db = pop @{ $self } ;
  1017.         $db->Txn() ;
  1018.     }
  1019.     #print "end disassociaten" ;
  1020. }
  1021. sub DESTROY
  1022. {
  1023.     my $self = shift ;
  1024.     $self->disassociate() ;
  1025.     # first close the close the transaction
  1026.     $self->_DESTROY() ;
  1027. }
  1028. package BerkeleyDB::Term ;
  1029. END
  1030. {
  1031.     close_everything() ;
  1032. }
  1033. package BerkeleyDB ;
  1034. # Autoload methods go after =cut, and are processed by the autosplit program.
  1035. 1;
  1036. __END__