File Coverage

blib/lib/WE/DB/Name.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             # -*- perl -*-
2              
3             #
4             # $Id: Name.pm,v 1.11 2004/02/26 11:10:58 eserte Exp $
5             # Author: Slaven Rezic
6             #
7             # Copyright (C) 2002 Slaven Rezic.
8             # This is free software; you can redistribute it and/or modify it under the
9             # terms of the GNU General Public License, see the file COPYING.
10              
11             #
12             # Mail: slaven@rezic.de
13             # WWW: http://we-framework.sourceforge.net
14             #
15              
16             package WE::DB::Name;
17              
18 1     1   4908 use base qw(WE::DB::Base);
  1         2  
  1         85  
19              
20 1     1   5 use strict;
  1         2  
  1         28  
21 1     1   5 use vars qw($VERSION $TIMEOUT);
  1         1  
  1         83  
22             $VERSION = sprintf("%d.%02d", q$Revision: 1.11 $ =~ /(\d+)\.(\d+)/);
23              
24             __PACKAGE__->mk_accessors(qw(DBFile DBTieArgs));
25              
26 1     1   317 use DB_File;
  0            
  0            
27             use Fcntl;
28              
29             =head1 NAME
30              
31             WE::DB::Name - a name to id database
32              
33             =head1 SYNOPSIS
34              
35             new WE::DB::Name $rootdb, $databasefilename;
36              
37             =head1 DESCRIPTION
38              
39             A class for a name-to-id database.
40              
41             =head2 CONSTRUCTOR new($class, $root, $file, %args)
42              
43             Usually called from C.
44              
45             =cut
46              
47             sub new {
48             my($class, $root, $file, %args) = @_;
49              
50             # XXX -db is not used yet! it's always DB_File for now
51             $args{-db} = "DB_File" unless defined $args{-db};
52             $args{-connect} = 1 unless defined $args{-connect};
53             $args{-readonly} = 0 unless defined $args{-readonly};
54             $args{-writeonly} = 0 unless defined $args{-writeonly};
55              
56             my $self = {};
57             bless $self, $class;
58              
59             my @tie_args;
60             if ($args{-readonly}) {
61             push @tie_args, O_RDONLY;
62             } elsif ($args{-writeonly}) {
63             push @tie_args, O_RDWR;
64             } else {
65             push @tie_args, O_RDWR|O_CREAT;
66             }
67              
68             push @tie_args, $args{-db} eq 'Tie::TextDir' ? 0770 : 0660;
69              
70             $self->DBFile($file);
71             $self->DBTieArgs(\@tie_args);
72              
73             $self->Root($root);
74             $self->Connected(0);
75              
76             if ($args{-connect} && $args{-connect} ne 'never') {
77             $self->connect;
78             }
79              
80             $self;
81             }
82              
83             =head2 METHODS
84              
85             =over 4
86              
87             =item insert($name, $id)
88              
89             Set a name for the specified id.
90              
91             =cut
92              
93             sub insert {
94             my($self, $name, $id) = @_;
95             $self->connect_if_necessary(sub {
96             $self->{DB}{$name} = $id;
97             });
98             }
99              
100             =item delete($name)
101              
102             Delete the specified name from the database
103              
104             =cut
105              
106             sub delete {
107             my($self, $name) = @_;
108             $self->connect_if_necessary(sub {
109             delete $self->{DB}{$name};
110             });
111             }
112              
113             =item get_id($name)
114              
115             Get the id for the specified name, or return undef, if there is no
116             such name in the database.
117              
118             =cut
119              
120             sub get_id {
121             my($self, $name) = @_;
122             $self->connect_if_necessary(sub {
123             $self->{DB}{$name};
124             });
125             }
126              
127             =item get_names($id)
128              
129             Return an array of all names for the specified object id.
130              
131             =cut
132              
133             sub get_names {
134             my($self, $id) = @_;
135             my @names;
136             $self->connect_if_necessary(sub {
137             while(my($name,$this_id) = each %{ $self->{DB} }) {
138             if ($id == $this_id) {
139             push @names, $name;
140             }
141             }
142             });
143             @names;
144             }
145              
146             =item update($add_objects, $del_objects)
147              
148             Update of the database by adding all names from C<$add_objects> and
149             deleting all names from C<$del_objects>. C<$add_objects> and
150             C<$del_objects> are array references with C objects.
151              
152             =cut
153              
154             sub update {
155             my($self, $add_objects, $del_objects) = @_;
156             for my $o (@$del_objects) {
157             if (defined $o->Name && $o->Name ne "") {
158             $self->delete($o->Name);
159             }
160             }
161             for my $o (@$add_objects) {
162             if (defined $o->Name && $o->Name ne "") {
163             $self->insert($o->Name, $o->Id);
164             }
165             }
166             }
167              
168             =item rebuild_db_contents($objdb)
169              
170             Complete rebuild of the name database from the object database.
171             C<$objdb> is optional, by default the standard C of the C
172             is used.
173              
174             =cut
175              
176             sub rebuild_db_contents {
177             my($self, $objdb) = @_;
178             $self->delete_db_contents;
179              
180             if (!$objdb) {
181             # $objdb = $self->Root->ObjDB;#XXX not working... why?
182             $objdb = $self->{Root}->ObjDB;
183             }
184             if (!$objdb) {
185             die "No object database reference specified";
186             }
187              
188             $self->connect_if_necessary(sub {
189             $objdb->walk($objdb->root_object->Id, sub {
190             my($id) = @_;
191             my $obj = $objdb->get_object($id);
192             my $name = $obj->Name;
193             if (defined $name && $name ne "") {
194             $self->{DB}{$name} = $obj->Id;
195             }
196             });
197             });
198             }
199              
200             =item delete_db_contents
201              
202             Delete all database contents
203              
204             =cut
205              
206             sub delete_db_contents {
207             my $self = shift;
208             $self->connect_if_necessary(sub {
209             my(@todel) = keys %{$self->{DB}};
210             foreach (@todel) {
211             delete $self->{DB}{$_};
212             }
213             });
214             }
215              
216             #XXX del:
217             # sub delete_db {
218             # my $self = shift;
219             # unlink $self->DBFile;
220             # }
221              
222             sub connect {
223             my $self = shift;
224             tie %{$self->{DB}}, "DB_File", $self->DBFile, @{$self->DBTieArgs}
225             or die("Can't tie DB_File database @{[$self->DBFile]} with args <@{$self->DBTieArgs}>: $!");
226             $self->Connected(1);
227             }
228              
229             # sub connect_if_necessary {
230             # my($self, $sub) = @_;
231             # my $connected = $self->Connected;
232             # my $do_disconnect;
233             # if (!$connected) {
234             # $self->connect;
235             # $do_disconnect=1;
236             # }
237             # my $wantarray = wantarray;
238             # my @r;
239             # eval {
240             # if ($wantarray) {
241             # @r = $sub->();
242             # } else {
243             # $r[0] = $sub->();
244             # }
245             # };
246             # my $err = $@;
247             # if ($do_disconnect) {
248             # $self->disconnect;
249             # }
250             # if ($err) {
251             # die $err;
252             # }
253             # if ($wantarray) {
254             # @r;
255             # } else {
256             # $r[0];
257             # }
258             # }
259              
260             =item disconnect
261              
262             Disconnect the database. No further access on the database may be done.
263              
264             =cut
265              
266             sub disconnect {
267             my $self = shift;
268             if ($self->Connected) {
269             eval {
270             untie %{ $self->{DB} };
271             };warn $@ if $@;
272             $self->Connected(0);
273             }
274             }
275              
276             =item all_names
277              
278             Return an array with all used names.
279              
280             =cut
281              
282             sub all_names {
283             my $self = shift;
284             $self->connect_if_necessary(sub {
285             keys %{ $self->{DB} };
286             });
287             }
288              
289             =item exists
290              
291             Return true if the name is already occupied.
292              
293             =cut
294              
295             sub exists {
296             my($self, $name) = @_;
297             $self->connect_if_necessary(sub {
298             exists $self->{DB}->{$name};
299             });
300             }
301              
302             1;
303              
304             __END__