1 package Onis::Data::Persistent::Dbm;
8 @AnyDBM_File::ISA = (qw(DB_File GDBM_File SDBM_File NDBM_File ODBM_File));
11 use Carp qw(carp confess);
12 use Fcntl (qw(O_RDWR O_CREAT));
15 use Onis::Config (qw(get_config));
19 Onis::Data::Persistent::Dbm - Storage backend using AnyDBM_File.
23 Storage backend that uses DBM files for storing data permanently.
25 =head1 CONFIGURATION OPTIONS
29 =item B<dbm_directory>: I<E<lt>dirE<gt>>
31 Directory in which the DBM-files are kept. Defaults to the B<var>-directory in
32 onis' main directory..
38 our $DBMDirectory = 'var';
39 if (get_config ('storage_dir'))
41 $DBMDirectory = get_config ('storage_dir');
45 $DBMDirectory = $ENV{'HOME'} . '/.onis/data';
47 $DBMDirectory =~ s#/+$##g;
49 if (!$DBMDirectory or !-d $DBMDirectory)
52 The directory ``$DBMDirectory'' does not exist or is not useable. Please
53 create it before running onis.
61 if ($::DEBUG & 0x0200)
74 my $caller = caller ();
80 my $id = $caller . ':' . $name;
83 $filename = "$DBMDirectory/$id.dbm";
85 if (exists ($Objects{$id}))
87 print STDERR $/, __FILE__, ": Name $name has been used in context $caller before.";
92 tie (%hash, 'AnyDBM_File', $filename, O_RDWR | O_CREAT, 0666) or die ("tie: $!");
94 $obj->{'data'} = tied %hash;
96 $obj->{'fields'} = [@fields];
97 $obj->{'num_fields'} = scalar (@fields);
98 $obj->{'field_index'} = {map { $_ => $i++ } (@fields)};
100 $obj->{'cache'} = {};
102 if ($::DEBUG & 0x0200)
104 my $prefix = __FILE__ . ': ';
105 my $dbg = Data::Dumper->Dump ([$obj], ['obj']);
106 $dbg =~ s/^/$prefix/mg; chomp ($dbg);
107 print STDOUT $/, $dbg;
110 $Objects{$id} = bless ($obj, $pkg);
111 return ($Objects{$id});
120 if ($obj->{'num_fields'} != scalar (@fields))
122 my $id = $obj->{'id'};
123 carp ("Number of fields do not match ($id).");
127 if ($::DEBUG & 0x0200)
129 print STDOUT $/, __FILE__, ': PUT(', $obj->{'id'}, ', ', $key, ') = (' . join (', ', @fields) . ')';
132 $obj->{'cache'}{$key} = [@fields];
141 my $db = $obj->{'data'};
143 if (!exists ($obj->{'cache'}{$key}))
145 $val = $db->FETCH ($key);
148 $obj->{'cache'}{$key} = undef;
152 $obj->{'cache'}{$key} = [split ($Alarm, $val)];
156 if (!defined ($obj->{'cache'}{$key}))
162 @ret = @{$obj->{'cache'}{$key}};
165 if ($::DEBUG & 0x0200)
167 print STDOUT $/, __FILE__, ': GET(', $obj->{'id'}, ', ', $key, ') = (' . join (', ', @ret) . ')';
177 my @field_indizes = ();
178 my $db = $obj->{'data'};
182 no strict (qw(subs));
183 for (($key, $val) = $db->FIRSTKEY (); defined ($key) and defined ($val); ($key, $val) = $db->NEXTKEY ($key))
185 next if (defined ($obj->{'cache'}{$key}));
187 $obj->{'cache'}{$key} = [split ($Alarm, $val)];
192 return (keys %{$obj->{'cache'}});
198 if (!defined ($obj->{'field_index'}{$field}))
200 my $id = $obj->{'id'};
201 print STDERR $/, __FILE__, ": $field is not a valid field ($id).";
204 push (@field_indizes, $obj->{'field_index'}{$field});
211 my $d = $obj->{'cache'}{$a}[$_] cmp $obj->{'cache'}{$b}[$_];
214 } (keys %{$obj->{'cache'}}));
221 my $db = $obj->{'data'};
223 if (exists ($obj->{'cache'}{$key}))
225 if (defined ($obj->{'cache'}{$key}))
228 $obj->{'cache'}{$key} = undef;
230 # It's known that the key doesn't exist..
235 $obj->{'cache'}{$key} = undef;
242 my $db = $obj->{'data'};
244 for (CORE::keys %{$obj->{'cache'}})
247 next unless (defined ($obj->{'cache'}{$key}));
249 my $val = join ($Alarm, @{$obj->{'cache'}{$key}});
251 $db->STORE ($key, $val);
252 delete ($obj->{'cache'}{$key});
260 for (CORE::keys (%Objects))
263 my $obj = $Objects{$key};
270 Florian octo Forster, L<octo at verplant.org>