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__ |