| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package AsciiDB::TagFile; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# Copyright (c) 1997-2001 Jose A. Rodriguez. All rights reserved. |
|
4
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify it |
|
5
|
|
|
|
|
|
|
# under the same terms as Perl itself. |
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
require Tie::Hash; |
|
8
|
|
|
|
|
|
|
@ISA = (Tie::Hash); |
|
9
|
|
|
|
|
|
|
|
|
10
|
6
|
|
|
6
|
|
5125
|
use Cwd; |
|
|
6
|
|
|
|
|
11
|
|
|
|
6
|
|
|
|
|
527
|
|
|
11
|
|
|
|
|
|
|
|
|
12
|
6
|
|
|
6
|
|
33
|
use vars qw($VERSION $catPathFileName); |
|
|
6
|
|
|
|
|
10
|
|
|
|
6
|
|
|
|
|
748
|
|
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
BEGIN { |
|
15
|
6
|
|
|
6
|
|
632
|
eval "use File::Spec"; |
|
|
6
|
|
|
6
|
|
40
|
|
|
|
6
|
|
|
|
|
11
|
|
|
|
6
|
|
|
|
|
77
|
|
|
16
|
|
|
|
|
|
|
$catPathFileName = ($@) ? |
|
17
|
0
|
|
|
|
|
0
|
sub { join('/', @_) } : # Unix way |
|
18
|
6
|
50
|
|
|
|
215
|
sub { File::Spec->catfile(@_) }; # Portable way |
|
|
175
|
|
|
|
|
194022
|
|
|
19
|
|
|
|
|
|
|
} |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
$VERSION = '1.06'; |
|
22
|
|
|
|
|
|
|
|
|
23
|
6
|
|
|
6
|
|
29
|
use Carp; |
|
|
6
|
|
|
|
|
9
|
|
|
|
6
|
|
|
|
|
4060
|
|
|
24
|
6
|
|
|
6
|
|
4346
|
use AsciiDB::TagRecord; |
|
|
6
|
|
|
|
|
15
|
|
|
|
6
|
|
|
|
|
7307
|
|
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub TIEHASH { |
|
27
|
6
|
|
|
6
|
|
4573
|
my $class = shift; |
|
28
|
6
|
|
|
|
|
34
|
my %params = @_; |
|
29
|
|
|
|
|
|
|
|
|
30
|
6
|
|
|
|
|
18
|
my $self = {}; |
|
31
|
6
|
|
33
|
|
|
41
|
$self->{_DIRECTORY} = $params{DIRECTORY} || cwd; |
|
32
|
6
|
|
50
|
|
|
32
|
$self->{_SUFIX} = $params{SUFIX} || ''; |
|
33
|
6
|
|
|
|
|
22
|
$self->{_SCHEMA} = $params{SCHEMA}; |
|
34
|
6
|
|
|
|
|
17
|
$self->{_READONLY} = $params{READONLY}; |
|
35
|
6
|
|
|
|
|
17
|
$self->{_FILEMODE} = $params{FILEMODE}; |
|
36
|
6
|
|
50
|
|
|
52
|
$self->{_LOCK} = $params{LOCK} || 0; |
|
37
|
6
|
|
|
|
|
18
|
$self->{_CACHESIZE} = $params{CACHESIZE}; |
|
38
|
|
|
|
|
|
|
|
|
39
|
6
|
50
|
|
|
|
91
|
unless (-d $self->{_DIRECTORY}) { |
|
40
|
0
|
|
|
|
|
0
|
croak "Directory '$params{DIRECTORY}' does not exist"; |
|
41
|
|
|
|
|
|
|
} |
|
42
|
|
|
|
|
|
|
|
|
43
|
6
|
100
|
|
|
|
28
|
if (defined $self->{_CACHESIZE}) { |
|
44
|
1
|
|
|
|
|
3
|
$self->{_CACHESIZE} = int($self->{_CACHESIZE}); |
|
45
|
|
|
|
|
|
|
|
|
46
|
1
|
50
|
|
|
|
7
|
if ($self->{_CACHESIZE} == 0) { |
|
|
|
50
|
|
|
|
|
|
|
47
|
0
|
|
|
|
|
0
|
undef $self->{_CACHESIZE}; |
|
48
|
|
|
|
|
|
|
} elsif ($self->{_CACHESIZE} < 1) { |
|
49
|
0
|
|
|
|
|
0
|
croak "Cache size should be >= 0 (0 means no cache)"; |
|
50
|
0
|
|
|
|
|
0
|
$self->{_CACHESIZE} = 1; |
|
51
|
|
|
|
|
|
|
} |
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# Number of internal keys (ie. '_key') |
|
55
|
6
|
|
|
|
|
29
|
$self->{_INTKEYCOUNT} = 1 + keys %$self; |
|
56
|
|
|
|
|
|
|
|
|
57
|
6
|
|
|
|
|
38
|
bless $self, $class; |
|
58
|
|
|
|
|
|
|
} |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
sub FETCH { |
|
61
|
173
|
|
|
173
|
|
1605
|
my ($self, $key) = @_; |
|
62
|
|
|
|
|
|
|
|
|
63
|
173
|
100
|
|
|
|
615
|
return $self->{$key} if exists ($self->{$key}); |
|
64
|
|
|
|
|
|
|
|
|
65
|
108
|
|
|
|
|
203
|
return $self->newRecord($key); |
|
66
|
|
|
|
|
|
|
} |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
sub STORE { |
|
69
|
2
|
|
|
2
|
|
4
|
my ($self, $key, $value) = @_; |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
# Return if the user is assigning an object to itself ($a{A} = $a{A}) |
|
72
|
2
|
100
|
66
|
|
|
13
|
return if exists $self->{$key} && $self->{$key} == $value; |
|
73
|
|
|
|
|
|
|
|
|
74
|
1
|
50
|
|
|
|
6
|
$self->newRecord($key) unless (exists $self->{$key}); |
|
75
|
|
|
|
|
|
|
|
|
76
|
1
|
|
|
|
|
1
|
my $field; |
|
77
|
1
|
|
|
|
|
2
|
foreach $field (keys %{$self->{$key}}) { |
|
|
1
|
|
|
|
|
8
|
|
|
78
|
4
|
|
|
|
|
17
|
$self->{$key}{$field} = $value->{$field}; |
|
79
|
|
|
|
|
|
|
} |
|
80
|
|
|
|
|
|
|
} |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub FIRSTKEY { |
|
83
|
1
|
|
|
1
|
|
17
|
my $self = shift; |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
# Current keys are the union of saved keys and new created but |
|
86
|
|
|
|
|
|
|
# not saved keys |
|
87
|
1
|
|
|
|
|
2
|
my %currentKeys; |
|
88
|
|
|
|
|
|
|
|
|
89
|
1
|
|
|
|
|
27
|
my $sufix = $self->{_SUFIX}; |
|
90
|
|
|
|
|
|
|
|
|
91
|
1
|
|
|
|
|
11
|
map { $currentKeys{$_} = 1 } |
|
|
1
|
|
|
|
|
5
|
|
|
92
|
2
|
|
|
|
|
41
|
map { $self->decodeKey($_) } |
|
93
|
1
|
|
|
|
|
6
|
grep { $_ =~ /(.+)\Q$sufix\E$/; $_ = $1 } |
|
|
2
|
|
|
|
|
11
|
|
|
94
|
|
|
|
|
|
|
$self->getDirFiles(); |
|
95
|
1
|
|
|
|
|
11
|
map { $currentKeys{$_} = 1 } grep(!/^_/, keys %$self); |
|
|
0
|
|
|
|
|
0
|
|
|
96
|
|
|
|
|
|
|
|
|
97
|
1
|
|
|
|
|
5
|
my @currentKeys = keys %currentKeys; |
|
98
|
1
|
|
|
|
|
3
|
$self->{_ITERATOR} = \@currentKeys; |
|
99
|
|
|
|
|
|
|
|
|
100
|
1
|
|
|
|
|
2
|
shift @{$self->{_ITERATOR}}; |
|
|
1
|
|
|
|
|
9
|
|
|
101
|
|
|
|
|
|
|
} |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub NEXTKEY { |
|
104
|
1
|
|
|
1
|
|
3
|
my $self = shift; |
|
105
|
|
|
|
|
|
|
|
|
106
|
1
|
|
|
|
|
2
|
shift @{$self->{_ITERATOR}}; |
|
|
1
|
|
|
|
|
7
|
|
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub EXISTS { |
|
110
|
2
|
|
|
2
|
|
18
|
my ($self, $key) = @_; |
|
111
|
|
|
|
|
|
|
|
|
112
|
2
|
100
|
66
|
|
|
13
|
$self->{$key} || -f $self->fileName($key) || 0; |
|
113
|
|
|
|
|
|
|
} |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub DELETE { |
|
116
|
55
|
|
|
55
|
|
328
|
my ($self, $key) = @_; |
|
117
|
|
|
|
|
|
|
|
|
118
|
55
|
100
|
|
|
|
109
|
return if $self->{_READONLY}; |
|
119
|
|
|
|
|
|
|
|
|
120
|
54
|
|
|
|
|
86
|
unlink $self->fileName($key); |
|
121
|
|
|
|
|
|
|
|
|
122
|
11
|
|
|
|
|
36
|
tied(%{$self->{$key}})->deleteRecord() |
|
|
54
|
|
|
|
|
187
|
|
|
123
|
54
|
100
|
|
|
|
119
|
if tied(%{$self->{$key}}); |
|
124
|
|
|
|
|
|
|
|
|
125
|
54
|
50
|
|
|
|
379
|
delete $self->{$key} if exists $self->{$key}; |
|
126
|
|
|
|
|
|
|
} |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub sync { |
|
129
|
1
|
|
|
1
|
0
|
7
|
my $self = shift; |
|
130
|
|
|
|
|
|
|
|
|
131
|
10
|
100
|
66
|
|
|
39
|
my @recordsToSync = grep { |
|
132
|
1
|
|
|
|
|
4
|
ref $_ && ref($_) eq 'HASH' && tied(%$_) |
|
133
|
1
|
|
|
|
|
2
|
} values %{$self}; |
|
134
|
|
|
|
|
|
|
|
|
135
|
1
|
|
|
|
|
2
|
my $record; |
|
136
|
1
|
|
|
|
|
2
|
foreach $record (@recordsToSync) { |
|
137
|
2
|
|
|
|
|
9
|
tied(%$record)->sync(); |
|
138
|
|
|
|
|
|
|
} |
|
139
|
|
|
|
|
|
|
} |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub purge { |
|
142
|
101
|
|
|
101
|
0
|
117
|
my $self = shift; |
|
143
|
101
|
|
|
|
|
100
|
my ($cacheSize) = @_; |
|
144
|
|
|
|
|
|
|
|
|
145
|
101
|
100
|
|
|
|
161
|
if (defined($cacheSize)) { |
|
146
|
100
|
|
|
|
|
143
|
my $dataRecords = scalar(keys %$self) - $self->{_INTKEYCOUNT}; |
|
147
|
100
|
100
|
|
|
|
224
|
return if $dataRecords < $cacheSize; |
|
148
|
|
|
|
|
|
|
} |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
# This works in 5.004 no 5.003 |
|
151
|
|
|
|
|
|
|
#delete @$self{grep !/^_/, keys %{$self}}; |
|
152
|
|
|
|
|
|
|
# instead we use this... |
|
153
|
9
|
|
|
|
|
12
|
foreach (grep !/^_/, keys %{$self}) { |
|
|
9
|
|
|
|
|
108
|
|
|
154
|
90
|
|
|
|
|
281
|
delete $self->{$_}; |
|
155
|
|
|
|
|
|
|
} |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
sub newRecord { |
|
159
|
109
|
|
|
109
|
0
|
120
|
my $self = shift; |
|
160
|
109
|
|
|
|
|
120
|
my ($key) = @_; |
|
161
|
|
|
|
|
|
|
|
|
162
|
109
|
100
|
|
|
|
307
|
$self->purge($self->{_CACHESIZE}) if defined($self->{_CACHESIZE}); |
|
163
|
|
|
|
|
|
|
|
|
164
|
109
|
|
|
|
|
128
|
my %record; |
|
165
|
109
|
|
|
|
|
201
|
tie %record, 'AsciiDB::TagRecord', |
|
166
|
|
|
|
|
|
|
FILENAME => $self->fileName($key), |
|
167
|
|
|
|
|
|
|
SCHEMA => $self->{_SCHEMA}, |
|
168
|
|
|
|
|
|
|
READONLY => $self->{_READONLY}, |
|
169
|
|
|
|
|
|
|
FILEMODE => $self->{_FILEMODE}; |
|
170
|
|
|
|
|
|
|
|
|
171
|
109
|
|
|
|
|
776
|
$self->{$key} = \%record; |
|
172
|
|
|
|
|
|
|
} |
|
173
|
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub encodeKey { |
|
175
|
171
|
|
|
171
|
0
|
159
|
my $self = shift; |
|
176
|
171
|
|
|
|
|
194
|
my ($key) = @_; |
|
177
|
|
|
|
|
|
|
|
|
178
|
171
|
|
|
|
|
331
|
my $encodeSub = $self->{_SCHEMA}{KEY}{ENCODE}; |
|
179
|
171
|
50
|
|
|
|
424
|
($encodeSub) ? &$encodeSub($key) : $key; |
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
sub decodeKey { |
|
183
|
1
|
|
|
1
|
0
|
3
|
my $self = shift; |
|
184
|
1
|
|
|
|
|
3
|
my ($key) = @_; |
|
185
|
|
|
|
|
|
|
|
|
186
|
1
|
|
|
|
|
3
|
my $decodeSub = $self->{_SCHEMA}{KEY}{DECODE}; |
|
187
|
1
|
50
|
|
|
|
8
|
($decodeSub) ? &$decodeSub($key) : $key; |
|
188
|
|
|
|
|
|
|
} |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
sub fileName { |
|
191
|
171
|
|
|
171
|
0
|
241
|
my $self = shift; |
|
192
|
171
|
|
|
|
|
311
|
my ($key) = $self->encodeKey(@_); |
|
193
|
|
|
|
|
|
|
|
|
194
|
171
|
|
|
|
|
1021
|
&$catPathFileName($$self{_DIRECTORY}, "$key$$self{_SUFIX}") |
|
195
|
|
|
|
|
|
|
} |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
sub getDirFiles { |
|
198
|
1
|
|
|
1
|
0
|
2
|
my $self = shift; |
|
199
|
|
|
|
|
|
|
|
|
200
|
1
|
|
|
|
|
5
|
local *DIR; |
|
201
|
1
|
50
|
|
|
|
70
|
opendir(DIR, $$self{_DIRECTORY}) |
|
202
|
|
|
|
|
|
|
|| die "Can't opendir $$self{_DIRECTORY}: $!"; |
|
203
|
1
|
|
|
|
|
42
|
my @files = grep { -f &$catPathFileName($$self{_DIRECTORY}, $_) } |
|
|
4
|
|
|
|
|
10
|
|
|
204
|
|
|
|
|
|
|
readdir(DIR); |
|
205
|
1
|
|
|
|
|
19
|
closedir DIR; |
|
206
|
|
|
|
|
|
|
|
|
207
|
1
|
|
|
|
|
6
|
@files; |
|
208
|
|
|
|
|
|
|
} |
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
1; |
|
211
|
|
|
|
|
|
|
__END__ |