c4ee232af4998539d162325da497fb864c94bbf6
[dbsrgits/DBM-Deep.git] / lib / DBM / Deep / Hash.pm
1 package DBM::Deep::Hash;
2
3 use 5.006_000;
4
5 use strict;
6 use warnings FATAL => 'all';
7
8 our $VERSION = $DBM::Deep::VERSION;
9
10 use base 'DBM::Deep';
11
12 sub _get_self {
13     eval { local $SIG{'__DIE__'}; tied( %{$_[0]} ) } || $_[0]
14 }
15
16 sub _repr { return {} }
17
18 sub TIEHASH {
19     my $class = shift;
20     my $args = $class->_get_args( @_ );
21     
22     $args->{type} = $class->TYPE_HASH;
23
24     return $class->_init($args);
25 }
26
27 sub FETCH {
28     my $self = shift->_get_self;
29     DBM::Deep->_throw_error( "Cannot use an undefined hash key." ) unless defined $_[0];
30     my $key = ($self->_engine->storage->{filter_store_key})
31         ? $self->_engine->storage->{filter_store_key}->($_[0])
32         : $_[0];
33
34     return $self->SUPER::FETCH( $key, $_[0] );
35 }
36
37 sub STORE {
38     my $self = shift->_get_self;
39     DBM::Deep->_throw_error( "Cannot use an undefined hash key." ) unless defined $_[0];
40     my $key = ($self->_engine->storage->{filter_store_key})
41         ? $self->_engine->storage->{filter_store_key}->($_[0])
42         : $_[0];
43     my $value = $_[1];
44
45     return $self->SUPER::STORE( $key, $value, $_[0] );
46 }
47
48 sub EXISTS {
49     my $self = shift->_get_self;
50     DBM::Deep->_throw_error( "Cannot use an undefined hash key." ) unless defined $_[0];
51     my $key = ($self->_engine->storage->{filter_store_key})
52         ? $self->_engine->storage->{filter_store_key}->($_[0])
53         : $_[0];
54
55     return $self->SUPER::EXISTS( $key );
56 }
57
58 sub DELETE {
59     my $self = shift->_get_self;
60     DBM::Deep->_throw_error( "Cannot use an undefined hash key." ) unless defined $_[0];
61     my $key = ($self->_engine->storage->{filter_store_key})
62         ? $self->_engine->storage->{filter_store_key}->($_[0])
63         : $_[0];
64
65     return $self->SUPER::DELETE( $key, $_[0] );
66 }
67
68 # Locate and return first key (in no particular order)
69 sub FIRSTKEY {
70     my $self = shift->_get_self;
71
72     $self->lock_shared;
73     
74     my $result = $self->_engine->get_next_key( $self );
75     
76     $self->unlock;
77     
78     return ($result && $self->_engine->storage->{filter_fetch_key})
79         ? $self->_engine->storage->{filter_fetch_key}->($result)
80         : $result;
81 }
82
83 # Return next key (in no particular order), given previous one
84 sub NEXTKEY {
85     my $self = shift->_get_self;
86
87     my $prev_key = ($self->_engine->storage->{filter_store_key})
88         ? $self->_engine->storage->{filter_store_key}->($_[0])
89         : $_[0];
90
91     $self->lock_shared;
92     
93     my $result = $self->_engine->get_next_key( $self, $prev_key );
94     
95     $self->unlock;
96     
97     return ($result && $self->_engine->storage->{filter_fetch_key})
98         ? $self->_engine->storage->{filter_fetch_key}->($result)
99         : $result;
100 }
101
102 sub first_key { (shift)->FIRSTKEY(@_) }
103 sub next_key  { (shift)->NEXTKEY(@_)  }
104
105 sub _copy_node {
106     my $self = shift;
107     my ($db_temp) = @_;
108
109     my $key = $self->first_key();
110     while ($key) {
111         my $value = $self->get($key);
112         $self->_copy_value( \$db_temp->{$key}, $value );
113         $key = $self->next_key($key);
114     }
115
116     return 1;
117 }
118
119 1;
120 __END__