File Coverage

blib/lib/List/Filter/Storage/YAML.pm
Criterion Covered Total %
statement 87 92 94.5
branch 8 8 100.0
condition n/a
subroutine 17 18 94.4
pod 7 7 100.0
total 119 125 95.2


line stmt bran cond sub pod time code
1             package List::Filter::Storage::YAML;
2 1     1   6 use base qw( List::Filter::StorageBase );
  1         2  
  1         1226  
3              
4             =head1 NAME
5              
6             List::Filter::Storage::YAML - plugin for filter storage via YAML files
7              
8             =head1 SYNOPSIS
9              
10             # This is a plugin, not intended for direct use.
11             # See: List:Filter:Storage
12              
13             use List::Filter::Storage::YAML;
14             my $storage = List::Filter::Storage::YAML->new( {
15             connect_to => $yaml_file,
16             } );
17              
18             my $filter = List::Filter->new(
19             { name => 'some_search_filter',
20             # [... see List::Filter ...]
21             } );
22              
23             $storage->save( $filter )
24              
25             my $named_filter = $storage->lookup( $name );
26              
27              
28             =head1 DESCRIPTION
29              
30             List::Filter::Storage::YAML is the plugin
31             that handles storage of List::Filter "filters"
32             (e.g. "filters", "transforms") to YAML files.
33              
34             =head2 METHODS
35              
36             =cut
37              
38 1     1   13 use 5.8.0;
  1         5  
  1         39  
39 1     1   5 use strict;
  1         2  
  1         28  
40 1     1   5 use warnings;
  1         2  
  1         24  
41 1     1   5 use Carp;
  1         2  
  1         55  
42 1     1   5 use Data::Dumper;
  1         2  
  1         49  
43 1     1   5 use Hash::Util qw( lock_keys unlock_keys );
  1         2  
  1         4  
44 1     1   58 use File::Path qw(mkpath);
  1         2  
  1         56  
45 1     1   6 use File::Basename qw(dirname fileparse);
  1         2  
  1         53  
46 1     1   5 use Env qw(HOME);
  1         2  
  1         8  
47 1     1   188 use YAML qw(DumpFile LoadFile);
  1         2  
  1         789  
48              
49             our $VERSION = '0.01';
50              
51             =item new
52              
53             Instantiates a new List::Filter::Profile object.
54              
55             Takes an optional hashref as an argument, with named fields
56             identical to the names of the object attributes.
57              
58             With no arguments, the newly created filter will be empty.
59              
60             =cut
61              
62             # Note: "new" (inherited from Class::Base)
63             # calls the following "init" routine automatically.
64              
65             =item init
66              
67             Initialize object attributes and then lock them down to prevent
68             accidental creation of new ones.
69              
70             Note: there is no leading underscore on name "init", though it's
71             arguably an "internal" routine (i.e. not likely to be of use to
72             client code).
73              
74             =cut
75              
76             sub init {
77 19     19 1 426 my $self = shift;
78 19         26 my $args = shift;
79 19         28 unlock_keys( %{ $self } );
  19         70  
80              
81 19         220 $self->SUPER::init( $args );
82              
83 19         31 lock_keys( %{ $self } );
  19         51  
84 19         149 return $self;
85             }
86              
87              
88             =head2 main methods
89              
90             =over
91              
92             =item lookup
93              
94             Given a filter name, returns a matching filter object, or undef.
95              
96             =cut
97              
98             sub lookup {
99 11     11 1 159 my $self = shift;
100 11         21 my $name = shift;
101              
102 11         34 my $filter_data = $self->filter_data;
103              
104 11         18 my $filter;
105 11 100       55 if ( my $filter_href = $filter_data->{ $name } ) {
106              
107             # convert this data into a filter object.
108 9         27 my $terms = $filter_href->{terms};
109 9         21 my $method = $filter_href->{method};
110 9         15 my $description = $filter_href->{description};
111 9         20 my $modifiers = $filter_href->{modifiers};
112              
113 9         51 my $filter_class = $self->define_filter_class;
114              
115 9         156 $filter = $filter_class->new(
116             { name => $name,
117             terms => $terms,
118             method => $method,
119             description => $description,
120             modifiers => $modifiers,
121             } );
122              
123             }
124              
125 11         117 return $filter;
126             }
127              
128             =item save
129              
130             Given a filter, adds it to the internal mass of "filter_data",
131             and saves the entire set to a yaml file.
132              
133             Excludes any filters that are named with a leading underscore.
134              
135             Returns a reference to the given filter object.
136              
137             =cut
138              
139             sub save {
140 8     8 1 15 my $self = shift;
141 8         13 my $filter = shift;
142              
143             # convert $filter object into a data structure,
144              
145 8         36 my $filter_name = $filter->name;
146              
147 8         35 my $method = $filter->method;
148 8         46 my $description = $filter->description;
149 8         30 my $terms = $filter->terms;
150 8         29 my $modifiers = $filter->modifiers;
151              
152 8         41 my $filter_href = { method => $method,
153             description => $description,
154             terms => $terms,
155             modifiers => $modifiers,
156             };
157              
158             # add it to the internal stash (replaces any existing one of same name)
159 8         31 my $filter_data = $self->filter_data;
160 8         25 $filter_data->{ $filter_name } = $filter_href;
161              
162             # write all filter_data out to the yaml file.
163 8         46 my $stash = $self->connect_to;
164             # DumpFile( $stash, $filter_data );
165              
166             # exclude filters named with a leading underscore
167 8         19 my $saves = {};
168 8         12 foreach my $name (keys %{ $filter_data }) {
  8         32  
169 20 100       61 unless ($name =~ m{^_}x) {
170 18         50 $saves->{ $name } = $filter_data->{ $name };
171             }
172             }
173 8         48 DumpFile( $stash, $saves );
174              
175 8         43116 return $filter;
176             }
177              
178             =back
179              
180             =head1 internal routines
181              
182             =over
183              
184             =item slurp_yaml_filter_data
185              
186             This method actually reads the yaml file, and stores the hash of hashes
187             structure inside of the object in "filter_data".
188              
189             =cut
190              
191             # Rather than call this from init, this method is used from the
192             # filter_data accessor, to conserve memory until the data is
193             # needed.
194             sub slurp_yaml_filter_data {
195 11     11 1 18 my $self = shift;
196              
197 11         13 my $filter_data;
198 11         49 my $stash = $self->connect_to;
199 11 100       482 if (-f $stash) {
200 9         57 $filter_data = LoadFile("$stash");
201 9         106704 $self->set_filter_data( $filter_data );
202             }
203 11         34 return $filter_data;
204             }
205              
206             =item list_filters
207              
208             Returns a list of all avaliable named filters.
209              
210             =cut
211              
212             sub list_filters {
213 0     0 1 0 my $self = shift;
214 0         0 my $filter_data = $self->filter_data;
215 0         0 my @names = keys (%{ $filter_data });
  0         0  
216 0         0 return \@names;
217             }
218              
219             =back
220              
221             =head2 special accessors (access the "extra" namespace)
222              
223             =over
224              
225             =item filter_data
226              
227             Getter for object attribute filter_data
228              
229             Note: the yaml file is not slurped in until an attempt is made
230             to access this data.
231              
232             =cut
233              
234             sub filter_data {
235 19     19 1 33 my $self = shift;
236 19         95 my $filter_data = $self->extra->{ filter_data };
237              
238             # if filter_data doesn't yet exist, slurp it now
239 19 100       66 unless( $filter_data ) {
240 11         46 $filter_data = $self->slurp_yaml_filter_data;
241             }
242              
243 19         46 return $filter_data;
244             }
245              
246             =item set_filter_data
247              
248             Setter for object attribute set_filter_data
249              
250             =cut
251              
252             sub set_filter_data {
253 9     9 1 24 my $self = shift;
254 9         20 my $filter_data = shift;
255 9         59 $self->extra->{ filter_data } = $filter_data;
256 9         23 return $filter_data;
257             }
258              
259             1;
260              
261              
262              
263             =back
264              
265             =head2 basic accessors (defined in List::Filter::Storage);
266              
267             =over
268              
269             =item connect_to
270              
271             Getter for object attribute connect_to
272              
273             =item set_connect_to
274              
275             Setter for object attribute set_connect_to
276              
277             =item owner
278              
279             Getter for object attribute owner
280              
281             =cut
282              
283             =item set_owner
284              
285             Setter for object attribute set_owner
286              
287             =cut
288              
289             =item password
290              
291             Getter for object attribute password
292              
293             =cut
294              
295             =item set_password
296              
297             Setter for object attribute set_password
298              
299             =cut
300              
301             =item attributes
302              
303             Getter for object attribute attributes
304              
305             =item set_attributes
306              
307             Setter for object attribute set_attributes
308              
309             =item extra
310              
311             Getter for object attribute extra
312              
313             =item set_extra
314              
315             Setter for object attribute set_extra
316              
317             =back
318              
319             =head2 INTERNALS
320              
321             Outside of this module, a "filter" is an object, inside of this
322             module, it's a hashref with four fields: "method", "description",
323             "terms", "modifiers". Note, that the "name" is excluded
324             from this list, because each of these hashrefs is stored inside
325             a larger hashref, keyed by "name" for rapid lookups.
326              
327             The external YAML file contains a copy of this data structure,
328             and it is read and written in it's entirety, and held cached in
329             memory inside this object.
330              
331             =head2 NOTES
332              
333             =head1 SEE ALSO
334              
335             L
336             L
337             L
338              
339             =head1 AUTHOR
340              
341             Joseph Brenner, Edoom@kzsu.stanford.eduE,
342             18 May 2007
343              
344             =head1 COPYRIGHT AND LICENSE
345              
346             Copyright (C) 2007 by Joseph Brenner
347              
348             This library is free software; you can redistribute it and/or modify
349             it under the same terms as Perl itself, either Perl version 5.8.2 or,
350             at your option, any later version of Perl 5 you may have available.
351              
352             =head1 BUGS
353              
354             None reported... yet.
355              
356             =cut