Fixed bug where overwrites weren't transaction-aware
[dbsrgits/DBM-Deep.git] / lib / DBM / Deep / Hash.pm
CommitLineData
6fe26b29 1package DBM::Deep::Hash;
2
460b1067 3use 5.6.0;
4
6fe26b29 5use strict;
460b1067 6use warnings;
6fe26b29 7
8use base 'DBM::Deep';
9
596e9574 10sub _get_self {
a4e2db58 11 eval { local $SIG{'__DIE__'}; tied( %{$_[0]} ) } || $_[0]
596e9574 12}
13
f9c33187 14sub _repr { shift;return { @_ } }
15
16sub _import {
17 my $self = shift;
18 my ($struct) = @_;
19
20 eval {
21 local $SIG{'__DIE__'};
22 foreach my $key (keys %$struct) {
23 $self->put($key, $struct->{$key});
24 }
25 }; if ($@) {
26 $self->_throw_error("Cannot import: type mismatch");
27 }
28
29 return 1;
30}
31
6fe26b29 32sub TIEHASH {
33 ##
34 # Tied hash constructor method, called by Perl's tie() function.
35 ##
36 my $class = shift;
0ca7ea98 37 my $args = $class->_get_args( @_ );
6fe26b29 38
39 $args->{type} = $class->TYPE_HASH;
40
41 return $class->_init($args);
42}
43
cb79ec85 44sub FETCH {
45 my $self = shift->_get_self;
460b1067 46 my $key = ($self->_fileobj->{filter_store_key})
47 ? $self->_fileobj->{filter_store_key}->($_[0])
cb79ec85 48 : $_[0];
49
359a01ac 50 return $self->SUPER::FETCH( $key, $_[0] );
cb79ec85 51}
52
81d3d316 53sub STORE {
54 my $self = shift->_get_self;
460b1067 55 my $key = ($self->_fileobj->{filter_store_key})
56 ? $self->_fileobj->{filter_store_key}->($_[0])
81d3d316 57 : $_[0];
58 my $value = $_[1];
59
359a01ac 60 return $self->SUPER::STORE( $key, $value, $_[0] );
81d3d316 61}
62
baa27ab6 63sub EXISTS {
64 my $self = shift->_get_self;
460b1067 65 my $key = ($self->_fileobj->{filter_store_key})
66 ? $self->_fileobj->{filter_store_key}->($_[0])
baa27ab6 67 : $_[0];
68
69 return $self->SUPER::EXISTS( $key );
70}
71
feaf1e6f 72sub DELETE {
73 my $self = shift->_get_self;
460b1067 74 my $key = ($self->_fileobj->{filter_store_key})
75 ? $self->_fileobj->{filter_store_key}->($_[0])
feaf1e6f 76 : $_[0];
77
359a01ac 78 return $self->SUPER::DELETE( $key, $_[0] );
feaf1e6f 79}
80
6fe26b29 81sub FIRSTKEY {
82 ##
83 # Locate and return first key (in no particular order)
84 ##
eea0d863 85 my $self = shift->_get_self;
6fe26b29 86
87 ##
6fe26b29 88 # Request shared lock for reading
89 ##
90 $self->lock( $self->LOCK_SH );
91
6736c116 92 my $result = $self->{engine}->get_next_key($self);
6fe26b29 93
94 $self->unlock();
95
460b1067 96 return ($result && $self->_fileobj->{filter_fetch_key})
97 ? $self->_fileobj->{filter_fetch_key}->($result)
6fe26b29 98 : $result;
99}
100
101sub NEXTKEY {
102 ##
103 # Return next key (in no particular order), given previous one
104 ##
eea0d863 105 my $self = shift->_get_self;
6fe26b29 106
460b1067 107 my $prev_key = ($self->_fileobj->{filter_store_key})
108 ? $self->_fileobj->{filter_store_key}->($_[0])
eea0d863 109 : $_[0];
6fe26b29 110
612969fb 111 my $prev_md5 = $self->{engine}{digest}->($prev_key);
6fe26b29 112
113 ##
6fe26b29 114 # Request shared lock for reading
115 ##
116 $self->lock( $self->LOCK_SH );
117
6736c116 118 my $result = $self->{engine}->get_next_key( $self, $prev_md5 );
6fe26b29 119
120 $self->unlock();
121
460b1067 122 return ($result && $self->_fileobj->{filter_fetch_key})
123 ? $self->_fileobj->{filter_fetch_key}->($result)
6fe26b29 124 : $result;
125}
126
127##
128# Public method aliases
129##
f9c33187 130sub first_key { (shift)->FIRSTKEY(@_) }
131sub next_key { (shift)->NEXTKEY(@_) }
132
133sub _copy_node {
898fd1fd 134 my $self = shift;
f9c33187 135 my ($db_temp) = @_;
136
137 my $key = $self->first_key();
138 while ($key) {
139 my $value = $self->get($key);
140 $self->_copy_value( \$db_temp->{$key}, $value );
141 $key = $self->next_key($key);
142 }
143
144 return 1;
145}
6fe26b29 146
1471;
148__END__