File Coverage

blib/lib/File/SimpleQuery.pm
Criterion Covered Total %
statement 36 36 100.0
branch 3 4 75.0
condition n/a
subroutine 8 8 100.0
pod 2 2 100.0
total 49 50 98.0


line stmt bran cond sub pod time code
1             package File::SimpleQuery;
2              
3 2     2   148919 use warnings;
  2         4  
  2         154  
4 2     2   11 use strict;
  2         3  
  2         75  
5              
6 2     2   12 use Carp qw/croak/;
  2         9  
  2         1085  
7              
8             =head1 NAME
9              
10             File::SimpleQuery - Query flat-files, simply!
11              
12             =head1 VERSION
13              
14             Version 0.01
15              
16             =cut
17              
18             our $VERSION = '0.01';
19              
20             =head1 SYNOPSIS
21              
22             Have you ever wanted to make queries against a flat-file, similar to a
23             database, but did not want to setup all the necessary database
24             machinery? Enter File::SimpleQuery, which is intended to allow you to
25             make simple sql-like queries against a file you specify.
26              
27              
28             Intended to make querying simple files easier. The file in question
29             is expected to have the first row be a header row, which is how it
30             knows whichs fields to select from.
31              
32             use File::SimpleQuery;
33              
34             my $delimiter = ',';
35             my $filename = 'test_file';
36             my $q = File::SimpleQuery->new($filename, $delimiter);
37              
38             my @results = $q->select(
39             [ qw/ field1 fieldn / ],
40             sub { my $fields = shift; return 1 if $fields->{field1} eq 'foo' },
41             );
42              
43              
44             =head1 FUNCTIONS
45              
46             =head2 new
47              
48             The constructor. You must specify the filename and the delimiter between rows
49              
50             =cut
51              
52             sub new
53             {
54 1     1 1 778 my ($class, $filename, $delim) = @_;
55 1         2 my $fh;
56 1 50       39 open($fh, '<', $filename) or croak "Unable to open file $filename\n";
57 1         12 my $headers = <$fh>;
58 1         2 chomp $headers;
59 1         22 return bless {
60             file => $fh,
61             delim => $delim,
62             headers => [ split /$delim/, $headers ]
63             }, $class;
64             }
65              
66             =head2 select ( \@field_names_to_select, \&where_sub, \@group_by_fields )
67              
68             Returns a list of hash-refs that match the lines in the file where the
69             where_sub evaluates to true, groupped by the group_by_fields
70              
71             =cut
72              
73             sub select
74             {
75 2     2 1 1528 my ($self, $fields, $where_sub, $group_by) = @_;
76 2         8 my $fh = $self->{file};
77              
78 2         3 my @rows;
79              
80 2         9 while ( my $line = <$fh> ) {
81 6         18 chomp $line;
82 6         15 my %fields = $self->_parse_line($line);
83 6 100       28 push @rows, { $self->_add_fields($fields, \%fields) }
84             if $where_sub->(\%fields);
85             }
86              
87 2         23 seek($fh, 0, 0);
88             # to skip headers;
89 2         13 <$fh>;
90              
91 2         11 return @rows;
92             }
93              
94             =head1 AUTHOR
95              
96             Ben Prew, C<< >>
97              
98             =head1 BUGS
99              
100             Please report any bugs or feature requests to
101             C, or through the web interface at
102             L.
103             I will be notified, and then you'll automatically be notified of progress on
104             your bug as I make changes.
105              
106             =head1 SUPPORT
107              
108             You can find documentation for this module with the perldoc command.
109              
110             perldoc File::SimpleQuery
111              
112             You can also look for information at:
113              
114             =over 4
115              
116             =item * AnnoCPAN: Annotated CPAN documentation
117              
118             L
119              
120             =item * CPAN Ratings
121              
122             L
123              
124             =item * RT: CPAN's request tracker
125              
126             L
127              
128             =item * Search CPAN
129              
130             L
131              
132             =back
133              
134             =head1 ACKNOWLEDGEMENTS
135              
136             =head1 COPYRIGHT & LICENSE
137              
138             Copyright 2006 Ben Prew, all rights reserved.
139              
140             This program is free software; you can redistribute it and/or modify it
141             under the same terms as Perl itself.
142              
143             =cut
144              
145              
146             sub _parse_line
147             {
148 6     6   10 my ($self, $line) = @_;
149 6         10 my $delim = $self->{delim};
150              
151 6         41 return _interleave(
152             $self->{headers},
153             [ split /$delim/, $line ]
154             );
155             }
156              
157             sub _interleave
158             {
159 6     6   10 my ($arr1, $arr2) = @_;
160              
161 6         6 my @interleaved;
162              
163 6         19 for (my $i = 0; $i < scalar @$arr1; $i++) {
164 30         79 push @interleaved, $arr1->[$i], $arr2->[$i];
165             }
166              
167 6         50 return @interleaved;
168             }
169              
170             sub _add_fields
171             {
172 4     4   27 my ($self, $fields_needed, $fields_and_values) = @_;
173              
174 4         8 return map { $_ => $fields_and_values->{$_} } @$fields_needed;
  8         104  
175             }
176              
177             1; # End of File::SimpleQuery