File Coverage

blib/lib/Data/Fallback/ConfFile.pm
Criterion Covered Total %
statement 59 67 88.0
branch 10 18 55.5
condition 4 12 33.3
subroutine 11 12 91.6
pod 0 8 0.0
total 84 117 71.7


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2              
3             package Data::Fallback::ConfFile;
4              
5 1     1   4 use strict;
  1         1  
  1         29  
6              
7 1     1   5 use Data::Fallback;
  1         1  
  1         28  
8 1     1   5 use vars qw(@ISA);
  1         1  
  1         826  
9             @ISA = qw(Data::Fallback);
10              
11             sub get_conffile_filename {
12 15     15 0 17 my $self = shift;
13            
14             # allows for /tmp/fallback/$primary_key
15             # to cache information for numerous keys like 1, 2, 7 for
16             # SELECT * FROM foo WHERE key = ?
17             # for example
18 15         34 my $primary_key = $self->get_cache_key('primary_key');
19              
20 15         29 my $return = $self->{hash}{content};
21 15 50       31 $return =~ s/\$primary_key/$primary_key/g if($primary_key);
22 15         47 return $return;
23             }
24              
25             sub _GET {
26 7     7   9 my $self = shift;
27              
28 7         9 my $return = 0;
29              
30 7         12 my $key = $self->get_conffile_filename . ".$self->{item}";
31              
32 7         22 my ($found_in_cache, $content) =
33             $self->check_cache('ConfFile', 'item', $key);
34              
35 7 100       15 if($found_in_cache) {
36 3         7 $self->{update}{item} = $content;
37 3         3 $return = 1;
38             } else {
39 4         9 my $contents = $self->get_content;
40 4         13 my $from_file_hash = contentToHash(\$contents);
41 4 100 66     33 if( $from_file_hash && (defined $from_file_hash->{$self->{hash}{item}}) && length $from_file_hash->{$self->{hash}{item}}) {
      66        
42 2         5 $self->{update}{group} = $from_file_hash;
43 2         5 $self->{update}{item} = $from_file_hash->{$self->{hash}{item}};
44 2         5 $self->set_cache('ConfFile', 'item', $self->get_conffile_filename . ".$self->{hash}{item}", $self->{update}{item});
45 2         4 $return = 1;
46             }
47             }
48              
49 7         21 return $return;
50             }
51              
52             sub SET_ITEM {
53 0     0 0 0 my $self = shift;
54 0         0 my $filename = $self->get_conffile_filename;
55 0 0 0     0 if($filename && -e $filename) {
56 0         0 my $content = Include($filename);
57 0         0 my $file_hash = contentToHash(\$content);
58 0 0 0     0 unless( (defined $file_hash->{$self->{item}}) && $file_hash->{$self->{item}} eq $self->{update}{item}) {
59 0         0 $file_hash->{$self->{item}} = $self->{update}{item};
60 0         0 write_conf_file($filename, $file_hash);
61             }
62             }
63             }
64              
65             sub SET_GROUP {
66 2     2 0 3 my $self = shift;
67 2         5 return write_conf_file($self->get_conffile_filename, $self->{update}{group});
68             }
69              
70             sub get_content {
71 4     4 0 5 my $self = shift;
72              
73 4         8 my $filename = $self->get_conffile_filename;
74 4         12 my ($found_in_cache, $content) =
75             $self->check_cache('ConfFile', 'group', $filename);
76              
77 4 100       59 if($found_in_cache) {
    50          
78             # already set in $content, so we're done
79             } elsif(-e $filename) {
80 2         4 $content = Include($filename);
81 2         13 $self->set_cache('ConfFile', 'group', $filename, $content);
82             } else {
83             # no value, no file => do nothing
84             }
85 4         8 return $content;
86             }
87              
88             sub contentToHash {
89 4     4 0 6 my $text_ref = shift;
90 4         59 my %hash = $$text_ref =~ /(.+?)\s+(.+)/g;
91 4         11 return \%hash;
92             }
93              
94             sub hashToContent {
95 2     2 0 4 my $hash_ref = shift;
96 2         3 my $content = '';
97 2         3 foreach(sort keys %{$hash_ref}) {
  2         11  
98 2 50       6 next unless($hash_ref->{$_});
99 2         7 $content .= "$_ $hash_ref->{$_}\n";
100             }
101 2         5 return $content;
102             }
103              
104             sub Include {
105 2     2 0 2 my $filename = shift;
106 2 50       29 return unless(-e $filename);
107 2         63 open(FILE, $filename);
108 2         52 my $content = join("", );
109 2         35 close(FILE);
110 2         5 return $content;
111             }
112              
113             sub write_conf_file {
114 2     2 0 4 my ($filename, $hash_ref) = @_;
115 2         5 my $txt = hashToContent($hash_ref);
116 2         175 open (FILE, ">$filename");
117 2         12 print FILE $txt;
118 2         64 close(FILE);
119             }
120              
121             =head1 NAME
122              
123             Data::Fallback::ConfFile - conf file package for Data::Fallback
124              
125             =head1 DESCRIPTION
126              
127             Data::Fallback looks through an array ref of hash refs, where each hash ref (a level) describes how to get data
128             from that level. Here's a typical level
129              
130             {
131             # refers to Data::Fallback::ConfFile
132             package => 'ConfFile',
133              
134             # content is a filename, $primary_key gets parsed in with the primary key for a given request
135             content => '/tmp/fallback/state_$primary_key',
136              
137             # this says the conf file will be updated with information from subsequent levels
138             accept_update => 'group',
139              
140             # this would say to only allow updates of individual items
141             #accept_update => 'item',
142             },
143              
144              
145             Please refer to the Data::Fallback perldoc for more information about lists and levels.
146              
147             =head1 EXAMPLE
148              
149             Let's say you have a list of directories that contain parallel conf files, like so
150              
151             # the 12 is some arbitrary primary key
152             /tmp/dir1/file_12
153             key1 key1 from dir1
154             key2 key2 from dir1
155              
156             /tmp/dir2/file_12
157             key2 key2 from dir2
158             key3 key3 from dir2
159              
160              
161             The code below could be used to fallback through them.
162              
163             #!/usr/bin/perl -w
164              
165             use strict;
166             use Data::Fallback;
167              
168             my $self = Data::Fallback->new({
169              
170             list => [
171             {
172             # filename
173             content => '/tmp/dir1/file_$primary_key',
174             },
175             {
176             content => '/tmp/dir2/file_$primary_key',
177             },
178             ],
179              
180             # the package looks first to the level, then to the object
181             # so if each level has the same package, you can just specify it in the object
182             package => 'ConfFile',
183              
184             # lists must be names
185             list_name => 'test_list',
186             });
187              
188             # 12 is the primary key (use // if no primary key), and key3 is the name of the key to retrieve
189             my $got = $self->get("/12/key3");
190              
191             =head1 FILE PARSING
192              
193             Right now, I just do something like
194              
195             split /\s+/, $line, 2
196              
197             to get a key/value pair for each line in the conf file. This is done through the method contentToHash, which you can
198             easily override for more complicated parsing. The actual line looks like something like this
199              
200             my %hash = $line =~ /(.+?)\s+(.+)/g;
201              
202             =head1 AUTHOR
203              
204             Copyright 2001-2002, Earl J. Cahill. All rights reserved.
205              
206             This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
207              
208             Address bug reports and comments to: cpan@spack.net.
209              
210             When sending bug reports, please provide the version of Data::Fallback, the version of Perl, and the name and version of the operating
211             system you are using.
212              
213             =cut
214              
215             1;