]>
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@patrick-canterino.de>
8 # License: 2-Clause BSD License
12 use Carp
qw(carp croak);
17 our $_BLOCKSIZE = 512;
23 $self->{'_index'} = { };
25 open(FILE
,'<'.$self->{'_dirfile'}) or carp
$!;
31 my ($key,@pos_and_siz_pair) = eval($line);
32 $self->{'_index'}->{$key} = \
@pos_and_siz_pair;
39 unlink($self->{'_bakfile'});
40 rename($self->{'_dirfile'},$self->{'_bakfile'});
42 open(FILE
,'>'.$self->{'_dirfile'}) or carp
$!;
44 while(my($key,$pos_and_siz_pair) = each(%{$self->{'_index'}})) {
45 print FILE
"'$key', ($pos_and_siz_pair->[0], $pos_and_siz_pair->[1])\n";
55 open(FILE
,'+<'.$self->{'_datfile'}) or carp
$!;
60 my $npos = int(($pos + $_BLOCKSIZE - 1) / $_BLOCKSIZE) * $_BLOCKSIZE;
62 print FILE
"\0" x
($npos-$pos);
70 return ($pos,length($val));
74 my ($self,$pos,$val) = @_;
77 open(FILE
,'+<'.$self->{'_datfile'}) or carp
$!;
83 return ($pos,length($val));
87 my ($self,$key,@pos_and_siz_pair) = @_;
90 $self->{'_index'}->{$key} = \
@pos_and_siz_pair;
92 open(FILE
,'>>'.$self->{'_dirfile'}) or carp
$!;
93 print FILE
"'$key', ($pos_and_siz_pair[0], $pos_and_siz_pair[1])\n";
98 my ($class,$file) = @_;
103 $hash->{'_dirfile'} = $file.'.dir';
104 $hash->{'_datfile'} = $file.'.dat';
105 $hash->{'_bakfile'} = $file.'.bak';
107 $hash->{'_index'} = { };
109 sysopen(FILE
,$hash->{'_datfile'},O_RDONLY
| O_CREAT
) or carp
$!;
112 my $self = bless($hash,$class);
119 my ($self,$key) = @_;
120 return exists($self->{'_index'}->{$key});
124 my ($self,$key) = @_;
127 my $pos = $self->{'_index'}->{$key}->[0];
128 my $siz = $self->{'_index'}->{$key}->[1];
130 open(FILE
,'<'.$self->{'_datfile'}) or carp
$!;
133 read(FILE
, my $dat, $siz);
140 my ($self,$key,$val) = @_;
142 if(not exists($self->{'_index'}->{$key})) {
143 $self->_addkey($key,$self->_addval($val));
146 my $pos = $self->{'_index'}->{$key}->[0];
147 my $siz = $self->{'_index'}->{$key}->[1];
149 my $oldblocks = int(($siz + $_BLOCKSIZE -1) / $_BLOCKSIZE);
150 my $newblocks = int((length($val) + $_BLOCKSIZE -1) / $_BLOCKSIZE);
152 if($newblocks <= $oldblocks) {
153 my @pos_and_siz_pair = $self->_setval($pos,$val);
154 $self->{'_index'}->{$key} = \
@pos_and_siz_pair;
157 my @pos_and_siz_pair = $self->_addval($val);
158 $self->{'_index'}->{$key} = \
@pos_and_siz_pair;
165 my $a = keys(%{$self->{'_index'}});
166 each %{$self->{'_index'}};
170 my ($self,$key) = @_;
171 delete($self->{'_index'}->{$key});
177 each %{$self->{'_index'}};
184 $self->{'_dirfile'} = undef;
185 $self->{'_datfile'} = undef;
186 $self->{'_bakfile'} = undef;
189 # it's true, baby ;-)
199 DumbDBM_File - Portable DBM implementation
205 # Opening a database file called "homer.db"
206 # Creating it if necessary
209 tie(%db,'DumbDBM_File','homer.db');
211 # Assigning some values
213 $db{'name'} = 'Homer';
214 $db{'wife'} = 'Marge';
215 $db{'child'} = 'Bart';
216 $db{'neighbor'} = 'Flanders';
218 # Print value of "name": Homer
222 # Overwriting a value
224 $db{'child'} = 'Lisa';
227 # The value remains in the database file, just the index entry gets removed,
228 # meaning you can't retrieve the value from the database file any more
230 delete($db{'neighbor'});
232 # Close the database file
238 This is a Perl implementation of Python's C<dumbdbm> / C<dbm.dumb> module. It
239 provides a simple DBM style database written entirely in Perl, requiring no
242 Beware that this module is slow and should only be used as a last resort
243 fallback when no more robust module like L<DB_File> is available.
245 This Perl implementation is fully compatible to the original Python one.
249 Consider having a database called example, you have up to three files:
255 This is an index file containing information for retrieving the values out of
256 the database. It is a text file containing the key, the file offset and the
259 =item example.dir.bak
261 This file B<may> contain a backup of the index file.
265 This is the database file containing the values separated by zero-bytes.
269 =head1 BUGS AND PROBLEMS
271 This module is a direct port of the Python module containing the same bugs and
274 - Seems to contain a bug when updating (this information was directly taken
275 from a comment in C<dumbdbm>'s source code)
277 - Free space is not reclaimed
279 - No concurrent access is supported (if two processes access the database, they
280 may mess up the index)
282 - This module always reads the whole index file and some updates the whole
289 Copyright (c) 2019, Patrick Canterino, <patrick@patrick-canterino.de>
291 This Perl module is licensed under the terms of the 2-Clause BSD License, see
292 file F<LICENSE> or L<https://opensource.org/licenses/BSD-2-Clause> for details.
296 DumbDBM_File was written by Patrick Canterino
297 L<patrick@patrick-canterino.de|mailto:patrick@patrick-canterino.de>.
299 L<https://www.patrick-canterino.de/>
301 If you wonder why I wrote this: I felt boring ;)
patrick-canterino.de