File Coverage

blib/lib/perfSONAR_PS/DB/File.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package perfSONAR_PS::DB::File;
2              
3 1     1   49911 use fields 'FILE', 'XML', 'LOGGER';
  1         2220  
  1         5  
4              
5 1     1   60 use strict;
  1         1  
  1         23  
6 1     1   4 use warnings;
  1         5  
  1         61  
7              
8             our $VERSION = 0.09;
9              
10             =head1 NAME
11              
12             perfSONAR_PS::DB::File - A module that provides methods for adding 'database
13             like' functions to files that contain XML markup.
14              
15             =head1 DESCRIPTION
16              
17             This purpose of this module is to ease the burden for someone who simply wishes
18             to use a flat file as an XML database. It should be known that this is not
19             recommended as performance will no doubt suffer, but the ability to do so can
20             be valuable. The module is to be treated as an object, where each instance of
21             the object represents a direct connection to a file. Each method may then be
22             invoked on the object for the specific database.
23              
24             =cut
25              
26 1     1   1493 use XML::LibXML;
  0            
  0            
27             use Log::Log4perl qw(get_logger :nowarn);
28             use Params::Validate qw(:all);
29              
30             use perfSONAR_PS::Common;
31             use perfSONAR_PS::ParameterValidation;
32              
33             =head2 new($package, { file })
34              
35             The only argument is a string representing the file to be opened.
36              
37             =cut
38              
39             sub new {
40             my ( $package, @args ) = @_;
41             my $parameters = validateParams( @args, { file => 0 } );
42              
43             my $self = fields::new($package);
44             $self->{LOGGER} = get_logger("perfSONAR_PS::DB::File");
45             if ( defined $parameters->{file} and $parameters->{file} ) {
46             $self->{FILE} = $parameters->{file};
47             }
48             return $self;
49             }
50              
51             =head2 setFile($self, { file })
52              
53             (Re-)Sets the name of the file to be used.
54              
55             =cut
56              
57             sub setFile {
58             my ( $self, @args ) = @_;
59             my $parameters = validateParams( @args, { file => 1 } );
60              
61             if ( $parameters->{file} =~ m/\.xml$/mx ) {
62             $self->{FILE} = $parameters->{file};
63             return 0;
64             }
65             else {
66             $self->{LOGGER}->error("Cannot set filename.");
67             return -1;
68             }
69             }
70              
71             =head2 openDB($self, { error })
72              
73             Opens the database, will return status of operation.
74              
75             =cut
76              
77             sub openDB {
78             my ( $self, @args ) = @_;
79             my $parameters = validateParams( @args, { error => 0 } );
80              
81             if ( defined $self->{FILE} ) {
82             my $parser = XML::LibXML->new();
83             $self->{XML} = $parser->parse_file( $self->{FILE} );
84             ${ $parameters->{error} } = q{} if ( defined $parameters->{error} );
85             return 0;
86             }
87             else {
88             my $msg = "Cannot open database, missing filename.";
89             $self->{LOGGER}->error($msg);
90             ${ $parameters->{error} } = $msg if ( defined $parameters->{error} );
91             return -1;
92             }
93             }
94              
95             =head2 closeDB($self, { error })
96              
97             Close the database, will return status of operation.
98              
99             =cut
100              
101             sub closeDB {
102             my ( $self, @args ) = @_;
103             my $parameters = validateParams( @args, { error => 0 } );
104              
105             if ( defined $self->{XML} and $self->{XML} ) {
106             if ( defined open( my $FILE, ">", $self->{FILE} ) ) {
107             print $FILE $self->{XML}->toString;
108             my $status = close($FILE);
109             if ( $status ) {
110             ${ $parameters->{error} } = q{} if ( defined $parameters->{error} );
111             return 0;
112             }
113             else {
114             my $msg = "File close failed.";
115             $self->{LOGGER}->error($msg);
116             ${ $parameters->{error} } = $msg if ( defined $parameters->{error} );
117             return -1;
118             }
119             }
120             else {
121             my $msg = "Couldn't open output file \"" . $self->{FILE} . "\"";
122             $self->{LOGGER}->error($msg);
123             ${ $parameters->{error} } = $msg if ( defined $parameters->{error} );
124             return -1;
125             }
126             }
127             else {
128             my $msg = "LibXML DOM structure not defined.";
129             $self->{LOGGER}->error($msg);
130             ${ $parameters->{error} } = $msg if ( defined $parameters->{error} );
131             return -1;
132             }
133             }
134              
135             =head2 query($self, { query, error } )
136              
137             Given a query, returns the results or nothing.
138              
139             =cut
140              
141             sub query {
142             my ( $self, @args ) = @_;
143             my $parameters = validateParams( @args, { query => 1, error => 0 } );
144              
145             my @results = ();
146             if ( $parameters->{query} ) {
147             $self->{LOGGER}->debug( "Query \"" . $parameters->{query} . "\" received." );
148             if ( defined $self->{XML} and $self->{XML} ) {
149             my $nodeset = $self->{XML}->find( $parameters->{query} );
150             foreach my $node ( @{$nodeset} ) {
151             push @results, $node->toString;
152             }
153             ${ $parameters->{error} } = q{} if ( defined $parameters->{error} );
154             return @results;
155             }
156             else {
157             my $msg = "LibXML DOM structure not defined.";
158             $self->{LOGGER}->error($msg);
159             ${ $parameters->{error} } = $msg if ( defined $parameters->{error} );
160             return -1;
161             }
162             }
163             else {
164             my $msg = "Missing argument.";
165             $self->{LOGGER}->error($msg);
166             ${ $parameters->{error} } = $msg if ( defined $parameters->{error} );
167             return -1;
168             }
169             }
170              
171             =head2 querySet($self, { query error } )
172              
173             Given a query, returns the results (as a nodeset) or nothing.
174              
175             =cut
176              
177             sub querySet {
178             my ( $self, @args ) = @_;
179             my $parameters = validateParams( @args, { query => 1, error => 0 } );
180              
181             if ( $parameters->{query} ) {
182             $self->{LOGGER}->debug( "Query \"" . $parameters->{query} . "\" received." );
183             if ( defined $self->{XML} and $self->{XML} ) {
184             ${ $parameters->{error} } = q{} if ( defined $parameters->{error} );
185             return $self->{XML}->find( $parameters->{query} );
186             }
187             else {
188             my $msg = "LibXML DOM structure not defined.";
189             $self->{LOGGER}->error($msg);
190             ${ $parameters->{error} } = $msg if ( defined $parameters->{error} );
191             return -1;
192             }
193             }
194             else {
195             my $msg = "Missing argument.";
196             $self->{LOGGER}->error($msg);
197             ${ $parameters->{error} } = $msg if ( defined $parameters->{error} );
198             return -1;
199             }
200             }
201              
202             =head2 count($self, { query error } )
203              
204             Counts the results of a query.
205              
206             =cut
207              
208             sub count {
209             my ( $self, @args ) = @_;
210             my $parameters = validateParams( @args, { query => 1, error => 0 } );
211              
212             if ( $parameters->{query} ) {
213             $self->{LOGGER}->debug( "Query \"" . $parameters->{query} . "\" received." );
214             if ( defined $self->{XML} and $self->{XML} ) {
215             my $nodeset = $self->{XML}->find( $parameters->{query} );
216             ${ $parameters->{error} } = q{} if ( defined $parameters->{error} );
217             return $nodeset->size();
218             }
219             else {
220             my $msg = "LibXML DOM structure not defined.";
221             $self->{LOGGER}->error($msg);
222             ${ $parameters->{error} } = $msg if ( defined $parameters->{error} );
223             return -1;
224             }
225             }
226             else {
227             my $msg = "Missing argument.";
228             $self->{LOGGER}->error($msg);
229             ${ $parameters->{error} } = $msg if ( defined $parameters->{error} );
230             return -1;
231             }
232             }
233              
234             =head2 getDOM($self, { error } )
235              
236             Returns the internal XML::LibXML DOM object. Will return "" on error.
237              
238             =cut
239              
240             sub getDOM {
241             my ( $self, @args ) = @_;
242             my $parameters = validateParams( @args, { error => 0 } );
243              
244             if ( defined $self->{XML} and $self->{XML} ) {
245             ${ $parameters->{error} } = q{} if ( defined $parameters->{error} );
246             return $self->{XML};
247             }
248             else {
249             my $msg = "LibXML DOM structure not defined.";
250             $self->{LOGGER}->error($msg);
251             ${ $parameters->{error} } = $msg if ( defined $parameters->{error} );
252             return -1;
253             }
254             }
255              
256             =head2 setDOM($self, { dom, error } )
257              
258             Sets the DOM object.
259              
260             =cut
261              
262             sub setDOM {
263             my ( $self, @args ) = @_;
264             my $parameters = validateParams( @args, { dom => 1, error => 0 } );
265              
266             if ( $parameters->{dom} ) {
267             $self->{XML} = $parameters->{dom};
268             ${ $parameters->{error} } = q{} if ( defined $parameters->{error} );
269             return 0;
270             }
271             else {
272             my $msg = "Missing argument.";
273             $self->{LOGGER}->error($msg);
274             ${ $parameters->{error} } = $msg if ( defined $parameters->{error} );
275             return -1;
276             }
277             }
278              
279             1;
280              
281             __END__