]>
git.p6c8.net - dumbdbm.git/blob - DumbDBM_File.pm
3 # DumbDBM_File - Portable DBM implementation
5 # Based on Python's dumbdbm / dbm.dumb
7 # Author: Patrick Canterino <patrick@patshaping.de>
11 use Carp
qw(carp croak);
16 our $_BLOCKSIZE = 512;
22 $self->{'_index'} = { };
24 open(FILE
,'<'.$self->{'_dirfile'}) or carp
$!;
30 my ($key,@pos_and_siz_pair) = eval($line);
31 $self->{'_index'}->{$key} = \
@pos_and_siz_pair;
38 unlink($self->{'_bakfile'});
39 rename($self->{'_dirfile'},$self->{'_bakfile'});
41 open(FILE
,'>'.$self->{'_dirfile'}) or carp
$!;
43 while(my($key,$pos_and_siz_pair) = each(%{$self->{'_index'}})) {
44 print FILE
"'$key', ($pos_and_siz_pair->[0], $pos_and_siz_pair->[1])\n";
54 open(FILE
,'+<'.$self->{'_datfile'}) or carp
$!;
59 my $npos = int(($pos + $_BLOCKSIZE - 1) / $_BLOCKSIZE) * $_BLOCKSIZE;
61 print FILE
"\0" x
($npos-$pos);
69 return ($pos,length($val));
73 my ($self,$pos,$val) = @_;
76 open(FILE
,'+<'.$self->{'_datfile'}) or carp
$!;
82 return ($pos,length($val));
86 my ($self,$key,@pos_and_siz_pair) = @_;
89 $self->{'_index'}->{$key} = \
@pos_and_siz_pair;
91 open(FILE
,'>>'.$self->{'_dirfile'}) or carp
$!;
92 print FILE
"'$key', ($pos_and_siz_pair[0], $pos_and_siz_pair[1])\n";
97 my ($class,$file) = @_;
102 $hash->{'_dirfile'} = $file.'.dir';
103 $hash->{'_datfile'} = $file.'.dat';
104 $hash->{'_bakfile'} = $file.'.bak';
106 $hash->{'_index'} = { };
108 sysopen(FILE
,$hash->{'_datfile'},O_RDONLY
| O_CREAT
) or carp
$!;
111 my $self = bless($hash,$class);
118 my ($self,$key) = @_;
119 return exists($self->{'_index'}->{$key});
123 my ($self,$key) = @_;
126 my $pos = $self->{'_index'}->{$key}->[0];
127 my $siz = $self->{'_index'}->{$key}->[1];
129 open(FILE
,'<'.$self->{'_datfile'}) or carp
$!;
132 read(FILE
, my $dat, $siz);
139 my ($self,$key,$val) = @_;
141 if(not exists($self->{'_index'}->{$key})) {
142 $self->_addkey($key,$self->_addval($val));
145 my $pos = $self->{'_index'}->{$key}->[0];
146 my $siz = $self->{'_index'}->{$key}->[1];
148 my $oldblocks = int(($siz + $_BLOCKSIZE -1) / $_BLOCKSIZE);
149 my $newblocks = int((length($val) + $_BLOCKSIZE -1) / $_BLOCKSIZE);
151 if($newblocks <= $oldblocks) {
152 my @pos_and_siz_pair = $self->_setval($pos,$val);
153 $self->{'_index'}->{$key} = \
@pos_and_siz_pair;
156 my @pos_and_siz_pair = $self->_addval($val);
157 $self->{'_index'}->{$key} = \
@pos_and_siz_pair;
164 my $a = keys(%{$self->{'_index'}});
165 each %{$self->{'_index'}};
169 my ($self,$key) = @_;
170 delete($self->{'_index'}->{$key});
176 each %{$self->{'_index'}};
183 $self->{'_dirfile'} = undef;
184 $self->{'_datfile'} = undef;
185 $self->{'_bakfile'} = undef;
188 # it's true, baby ;-)
198 DumbDBM_File - Portable DBM implementation
204 # Opening a database file called "homer.db"
205 # Creating it if necessary
208 tie(%db,'DumbDBM_File','homer.db');
210 # Assigning some values
212 $db{'name'} = 'Homer';
213 $db{'wife'} = 'Marge';
214 $db{'child'} = 'Bart';
215 $db{'neighbor'} = 'Flanders';
217 # Print value of "name": Homer
221 # Overwriting a value
223 $db{'child'} = 'Lisa';
226 # The value remains in the database file, just the index entry gets removed,
227 # meaning you can't retrieve the value from the database file any more
229 delete($db{'neighbor'});
231 # Close the database file
237 This is a Perl implementation of Python's C<dumbdbm> / C<dbm.dumb> module. It
238 provides a simple DBM style database written entirely in Perl, requiring no
241 Beware that this module is slow and should only be used as a last resort
242 fallback when no more robust module like L<DB_File> is available.
244 This Perl implementation is fully compatible to the original Python one.
248 Consider having a database called example, you have up to three files:
254 This is an index file containing information for retrieving the values out of
255 the database. It is a text file containing the key, the file offset and the
258 =item example.dir.bak
260 This file B<may> containg a backup of the index file.
264 This is the database file containing the values separated by zeros.
268 =head1 BUGS AND PROBLEMS
270 This module is a direct port of the Python module containing the same bugs and
273 - Seems to contain a bug when updating (this information was directly taken
274 from a comment in C<dumbdbm>'s source code)
276 - Free space is not reclaimed
278 - No concurrent access is supported (if two processes access the database, they
279 may mess up the index)
281 - This module always reads the whole index file and some updates the whole
290 DumbDBM_File was written by Patrick Canterino
291 L<patrick@patshaping.de|mailto:patrick@patshaping.de>.
293 L<http://www.patshaping.de/>
295 If you wonder why I wrote this: I felt boring ;)
patrick-canterino.de