e315a5df8a4e0844cc13b5dfed41b3f218285638
[dbsrgits/DBM-Deep.git] / lib / DBM / Deep / Hash.pm
1 package DBM::Deep::Hash;
2
3 use strict;
4
5 use base 'DBM::Deep';
6
7 sub _get_self {
8     eval { tied( %{$_[0]} ) } || $_[0]
9 }
10
11 sub TIEHASH {
12     ##
13     # Tied hash constructor method, called by Perl's tie() function.
14     ##
15     my $class = shift;
16     my $args;
17     if (scalar(@_) > 1) {
18         if ( @_ % 2 ) {
19             $class->_throw_error( "Odd number of parameters to TIEHASH" );
20         }
21         $args = {@_};
22     }
23     #XXX This use of ref() is bad and is a bug
24     elsif (ref($_[0])) { $args = $_[0]; }
25     else { $args = { file => shift }; }
26     
27     $args->{type} = $class->TYPE_HASH;
28
29     return $class->_init($args);
30 }
31
32 sub STORE {
33     my $self = shift->_get_self;
34         my $key = ($self->root->{filter_store_key})
35         ? $self->root->{filter_store_key}->($_[0])
36         : $_[0];
37     my $value = $_[1];
38
39     return $self->SUPER::STORE( $key, $value );
40 }
41
42 sub FIRSTKEY {
43         ##
44         # Locate and return first key (in no particular order)
45         ##
46     my $self = $_[0]->_get_self;
47
48         ##
49         # Make sure file is open
50         ##
51         if (!defined($self->fh)) { $self->_open(); }
52         
53         ##
54         # Request shared lock for reading
55         ##
56         $self->lock( $self->LOCK_SH );
57         
58         my $result = $self->_get_next_key();
59         
60         $self->unlock();
61         
62         return ($result && $self->root->{filter_fetch_key})
63         ? $self->root->{filter_fetch_key}->($result)
64         : $result;
65 }
66
67 sub NEXTKEY {
68         ##
69         # Return next key (in no particular order), given previous one
70         ##
71     my $self = $_[0]->_get_self;
72
73         my $prev_key = ($self->root->{filter_store_key})
74         ? $self->root->{filter_store_key}->($_[1])
75         : $_[1];
76
77         my $prev_md5 = $DBM::Deep::DIGEST_FUNC->($prev_key);
78
79         ##
80         # Make sure file is open
81         ##
82         if (!defined($self->fh)) { $self->_open(); }
83         
84         ##
85         # Request shared lock for reading
86         ##
87         $self->lock( $self->LOCK_SH );
88         
89         my $result = $self->_get_next_key( $prev_md5 );
90         
91         $self->unlock();
92         
93         return ($result && $self->root->{filter_fetch_key})
94         ? $self->root->{filter_fetch_key}->($result)
95         : $result;
96 }
97
98 ##
99 # Public method aliases
100 ##
101 *first_key = *FIRSTKEY;
102 *next_key = *NEXTKEY;
103
104 1;
105 __END__