File Coverage

blib/lib/Wikileaks/AfWD.pm
Criterion Covered Total %
statement 15 141 10.6
branch 0 44 0.0
condition 0 3 0.0
subroutine 5 11 45.4
pod 6 6 100.0
total 26 205 12.6


line stmt bran cond sub pod time code
1             package Wikileaks::AfWD;
2              
3 1     1   23364 use warnings;
  1         3  
  1         32  
4 1     1   7 use strict;
  1         2  
  1         33  
5 1     1   2353 use DBI;
  1         20358  
  1         71  
6 1     1   1178 use Text::NeatTemplate;
  1         4674  
  1         39  
7 1     1   1036 use Text::Autoformat qw(autoformat);
  1         71910  
  1         2068  
8              
9             =head1 NAME
10              
11             Wikileaks::AfWD - Useful utilities for searching the Afganistan War Diary.
12              
13             =head1 VERSION
14              
15             Version 0.1.0
16              
17             =cut
18              
19             our $VERSION = '0.1.0';
20              
21              
22             =head1 SYNOPSIS
23              
24             use Wikileaks::AfWD;
25              
26             my $foo = Wikileaks::AfWD->new();
27             ...
28              
29             =head1 METHODS
30              
31             =head2 new
32              
33             This initiates the object.
34              
35             It takes a optional hash reference.
36              
37             =head3 hash ref
38              
39             If both "dbb" and "dbhCS" is specified, "dbi" will be used.
40              
41             If none are specified, it checks for envriromental variables.
42              
43             =head4 dbi
44              
45             This is the DBH to use.
46              
47             =head4 dbiCS
48              
49             This is the DBI connection string to use.
50              
51             =head4 dbiUser
52              
53             If using "dbhCS", this will be checked for the user name
54             to use.
55              
56             If not specified, it will be set to "".
57              
58             =head4 dbiPass
59              
60             If using "dbhCS", this will be checked for the password
61             to use.
62              
63             If not specified, it will be set to "".
64              
65             =head4 table
66              
67             This is the table to search.
68              
69             If not specified, "war_diary" is used.
70              
71             =cut
72              
73             sub new{
74 0     0 1   my %args;
75 0 0         if(defined($_[1])){
76 0           %args= %{$_[1]};
  0            
77             }
78 0           my $method='new';
79              
80 0           my $self={
81             error=>undef,
82             perror=>undef,
83             errorString=>'',
84             module=>'Wikileaks-AfWD',
85             };
86 0           bless $self;
87              
88             #gets the DBI if we have it
89 0 0         if (defined( $args{dbh} )) {
90 0 0         if ($args{dbh} ne 'DBI::db') {
91 0           $self->error=1;
92 0           $self->{perror}=1;
93 0           $self->{errorString}="The database handle passed is not a 'DBI::db' object";
94 0           warn($self->{module}.' '.$method.':'.$self->{error}.': '.$self->{errorString});
95 0           return $self;
96             }
97 0           $self->{dbh}=$args{dbh};
98             }
99              
100             #if we still don't have a DBH yet, see if it was specified
101 0 0 0       if ( (!defined( $self->{dbh} )) && (defined( $args{dbiCS} )) ) {
102             #gets the user to use for connecting to the the server
103 0           my $user;
104 0 0         if(defined( $args{dbiUser} )){
105 0           $user=$args{dbiUser};
106             }
107             #gets the password to use for connecting to the the server
108 0           my $pass;
109 0 0         if(defined( $args{dbiPass} )){
110 0           $pass=$args{dbiPass};
111             }
112              
113             #attempt to connect
114 0           my $dbh=DBI->connect($args{dbiCS}, $user, $pass);
115 0 0         if (!defined( $dbh )) {
116 0           $self->{error}=2;
117 0           $self->{perror}=1;
118 0           $self->{errorString}="Failed to connect to the database";
119 0           warn($self->{module}.' '.$method.':'.$self->{error}.': '.$self->{errorString});
120 0           return $self;
121             }
122 0           $self->{dbh}=$dbh;
123             }
124              
125             #if we still don't have it, try fetching it via the environmental variable
126 0 0         if (!defined( $self->{dbh} )) {
127             #error if $ENV{AfWD_DBICS} is not defined... this being the final chance to get it
128 0 0         if (!defined( $ENV{AfWD_DBICS} )) {
129 0           $self->{error}=2;
130 0           $self->{perror}=1;
131 0           $self->{errorString}='$ENV{AfWD_DBICS} not defined';
132 0           warn($self->{module}.' '.$method.':'.$self->{error}.': '.$self->{errorString});
133 0           return $self;
134             }
135              
136             #gets the user to use for connecting to the the server
137 0           my $user;
138 0 0         if(defined( $ENV{AfWD_DBIUSER} )){
139 0           $user=$ENV{AfWD_DBIUSER};
140             }
141             #gets the password to use for connecting to the the server
142 0           my $pass;
143 0 0         if(defined( $ENV{AfWD_DBIPASS} )){
144 0           $pass=$ENV{AfWD_DBIPASS};
145             }
146              
147             #attempt to connect
148 0           my $dbh=DBI->connect($ENV{AfWD_DBICS}, $user, $pass);
149 0 0         if (!defined( $dbh )) {
150 0           $self->{error}=2;
151 0           $self->{perror}=1;
152 0           $self->{errorString}="Failed to connect to the database";
153 0           warn($self->{module}.' '.$method.':'.$self->{error}.': '.$self->{errorString});
154 0           return $self;
155             }
156 0           $self->{dbh}=$dbh;
157             }
158              
159 0 0         if (!defined($args{table})) {
160 0           $self->{table}="war_diary";
161             }
162              
163 0           return $self;
164             }
165              
166             =head2 search
167              
168             This performs a search. This searches the table, specified in new, and returns the resutls.
169              
170             One arguement is taken and is appended to the select statement.
171              
172             For example if we wish to select every report where the dcolor is "BLUE", we would set it to
173             "dcolor='BLUE'", making the resulting string "SELECT * FROM war_diary WHERE dcolor='BLUE';".
174              
175             What is returned is the resulting statement handle, post execute.
176              
177             my $sth=$foo->search($WHERE);
178              
179             =cut
180              
181             sub search{
182 0     0 1   my $self=$_[0];
183 0           my $search=$_[1];
184              
185             #blanks any previous errors
186 0           $self->errorblank;
187 0 0         if ($self->{error}) {
188 0           return undef;
189             }
190              
191             #default to it being blank if there is nothing
192 0 0         if (!defined( $search )) {
193 0           $search='';
194             }else {
195 0           $search='WHERE '.$search;
196             }
197              
198 0           my $sth=$self->{dbh}->prepare('SELECT * FROM '.$self->{table}.' '.$search);
199              
200 0           $sth->execute;
201              
202 0           return $sth;
203             }
204              
205             =head2 format
206              
207             This formats the statement handler from the search method.
208              
209             =head3 args hash ref
210              
211             =head4 joiner
212              
213             This is what should be used to join the entries.
214              
215             The default is
216             "\n\n---------------------------------------------------------------------------\n\n".
217              
218             =head4 print
219              
220             If defined, it will be printed and '' will be returned.
221              
222             =head4 sth
223              
224             This is the statement handler to use. Generally what is returned from
225             the search method.
226              
227             =head4 template
228              
229             This is the Text::NeatTemplate to use.
230              
231             =cut
232              
233             sub format{
234 0     0 1   my $self=$_[0];
235 0           my %args;
236 0 0         if (defined($_[1])) {
237 0           %args=%{$_[1]};
  0            
238             }
239 0           my $method='format';
240              
241             #blanks any previous errors
242 0           $self->errorblank;
243 0 0         if ($self->{error}) {
244 0           return undef;
245             }
246              
247             #makes sure we have $sth
248 0 0         if (!defined($args{sth})) {
249 0           $self->{error}=3;
250 0           $self->{errorString}="No statement handle passed";
251 0           warn($self->{module}.' '.$method.':'.$self->{error}.': '.$self->{errorString});
252 0           return $self;
253             }
254 0           my $sth=$args{sth};
255              
256             #
257 0           my $template='ReportKey: {$reportkey}'."\n".
258             'TrackingNumber: {$trackingnumber}'."\n".
259             "\n".
260             'Date: {$date}'."\n".
261             'Type: {$type}'."\n".
262             'Category: {$category}'."\n".
263             'Region: {$region}'."\n".
264             'AttackOn: {aAttackon}'."\n".
265             'ComplexAttack: {$complexattack}'."\n".
266             'ReportingUnit: {$reportingunit}'."\n".
267             'UnitName: {$unitname}'."\n".
268             'TypeOfUnit: {$typeofunit}'."\n".
269             "\n".
270             'FriendlyWIA: {$friendlywia}'."\n".
271             'FriendlyKIA: {$friendlykia}'."\n".
272             'HostNationWIA: {$hostnationwia}'."\n".
273             'HostNationKIA: {$hostnationkia}'."\n".
274             'CivilianWIA: {$civilianwia}'."\n".
275             'CivilianKIA: {$civiliankia}'."\n".
276             'EnemyWIA: {$enemywia}'."\n".
277             'EnemyKIA: {$enemykia}'."\n".
278             'EnemyDetained: {$enemydetained}'."\n".
279             "\n".
280             'MGRS: {$MGRS}'."\n".
281             'Latitude: {$latitude}'."\n".
282             'Longitude: {$longitude}'."\n".
283             "\n".
284             'OriginatorGroup: {$originatorgroup}'."\n".
285             'UpdatedByGroup: {$updatedbygroup}'."\n".
286             'CCIR: {$ccir}'."\n".
287             'Sigact: {$sigact}'."\n".
288             'Affiliation: {$affiliation}'."\n".
289             'DColor: {$dcolor}'."\n".
290             'classification: {$classification}'."\n".
291             "\n".
292             'Title: {$title}'."\n\n".
293             '{$summary}';
294 0 0         if (defined( $args{template} )) {
295 0           $template=$args{template};
296             }
297              
298             #the template object that will be filled in
299 0           my $tobj = Text::NeatTemplate->new();
300              
301             #used to join each item
302 0           my $joiner="\n\n---------------------------------------------------------------------------\n\n";
303              
304             #does the initial one and forms the text
305 0           my $hashref=$sth->fetchrow_hashref;
306              
307             #hash cleanup... some servers will return it with proper capilization
308             #and others, Pg, will return it all lower case... so lc it all
309 0           my @keys=%{ $hashref };
  0            
310 0           my $int=0;
311 0           while (defined( $keys[$int] )) {
312 0           $hashref->{ lc( $keys[$int] ) }=$hashref->{ $keys[$int] };
313              
314 0           $int++;
315             }
316              
317 0           $hashref->{summary}=~s/\&\;apos\;/\'/g;
318 0           $hashref->{summary}=~s/\&\;quot\;/\"/g;
319 0           $hashref->{summary}=autoformat($hashref->{summary}, {
320             right=>72,
321             lists =>'',
322             all=>1,
323             });
324 0           my $text=$tobj->fill_in(
325             data_hash=>$hashref,
326             template=>$template
327             );
328              
329             #process each one
330 0           $hashref=$sth->fetchrow_hashref;
331 0           while (defined( $hashref )) {
332             #hash cleanup... some servers will return it with proper capilization
333             #and others, Pg, will return it all lower case... so lc it all
334 0           my @keys=%{ $hashref };
  0            
335 0           my $int=0;
336 0           while (defined( $keys[$int] )) {
337 0           $hashref->{ lc( $keys[$int] ) }=$hashref->{ $keys[$int] };
338            
339 0           $int++;
340             }
341              
342 0           $hashref->{summary}=~s/\&\;apos\;/\'/g;
343 0           $hashref->{summary}=~s/\&\;amp\;apos\;/\'/g;
344 0           $hashref->{summary}=~s/\&\;quot\;/\"/g;
345              
346 0           $hashref->{summary}=autoformat($hashref->{summary}, {
347             right=>72,
348             lists =>'',
349             all=>1,
350             });
351            
352             #found one case this is true for while watching stderr
353 0 0         if (!defined($hashref->{summary})) {
354 0           $hashref->{summary}='';
355             }
356              
357 0           $text=$text.$joiner.$tobj->fill_in(
358             data_hash=>$hashref,
359             template=>$template,
360             );
361              
362 0 0         if (defined( $args{print} )) {
363 0           print $text;
364 0           $text='';
365             }
366              
367 0           $hashref=$sth->fetchrow_hashref;
368             }
369              
370 0           return $text;
371             }
372              
373             =head1 ERROR RELATED METHODS
374              
375             =head2 error
376              
377             This returns the current error code if one is set. If undef/evaulates as false
378             then no error is present. Other wise one is.
379              
380             if($foo->error){
381             warn('error '.$foo->error.': '.$foo->errorString);
382             }
383              
384             =cut
385              
386             sub error{
387 0     0 1   return $_[0]->{error};
388             }
389              
390             =head2 errorString
391              
392             This returns the current error string. A return of "" means no error is present.
393              
394             my $errorString=$foo->errorString;
395              
396             =cut
397              
398             sub errorString{
399 0     0 1   return $_[0]->{errorString};
400             }
401              
402             =head2 errorblank
403              
404             This blanks the error storage and is only meant for internal usage.
405              
406             It does the following.
407              
408             $self->{error}=undef;
409             $self->{errorString}="";
410              
411             =cut
412              
413             #blanks the error flags
414             sub errorblank{
415 0     0 1   my $self=$_[0];
416 0           my $function='errorBlank';
417            
418 0 0         if ($self->{perror}) {
419 0           warn($self->{error}.' '.$function.': A permanent error is set. error="'.
420             $self->{error}.'" errorString="'.$self->{errorSting}.'"');
421 0           return undef;
422             }
423            
424 0           $self->{error}=undef;
425 0           $self->{errorString}="";
426              
427 0           return 1;
428             }
429              
430             =head1 ERROR CODES
431              
432             The error code is contianed in $foo->{error} and a extended description can be
433             found in $foo->{errorString}. If any module ever sets $foo->{perror} then the error
434             is permanent and none of the methods are usable.
435              
436             =head2 1
437              
438             The database handle passed is not a "DBI::db" object.
439              
440             =head2 2
441              
442             Failed to create the DBI connection.
443              
444             =head2 3
445              
446             No statement handle passed.
447              
448             =head1 ENVIRONMENTAL VARIABLES
449              
450             =head2 AfWD_DBICS
451              
452             If neither "dbiCS" or "dbh" is specified for the new method, this will be used.
453              
454             =head2 AfWD_DBIUSER
455              
456             This if $ENV{AfWD_DBICS} is used, this will be checked for the user.
457              
458             =head2 AfWD_DBIPASS
459              
460             This if $ENV{AfWD_DBICS} is used, this will be checked for the password.
461              
462             =head1 AUTHOR
463              
464             Zane C. Bowers-Hadley, C<< >>
465              
466             =head1 BUGS
467              
468             Please report any bugs or feature requests to C, or through
469             the web interface at L. I will be
470             notified, and then you'll automatically be notified of progress on your bug as I make changes.
471              
472              
473             =head1 SUPPORT
474              
475             You can find documentation for this module with the perldoc command.
476              
477             perldoc Wikileaks::AfWD
478              
479              
480             You can also look for information at:
481              
482             =over 4
483              
484             =item * RT: CPAN's request tracker
485              
486             L
487              
488             =item * AnnoCPAN: Annotated CPAN documentation
489              
490             L
491              
492             =item * CPAN Ratings
493              
494             L
495              
496             =item * Search CPAN
497              
498             L
499              
500             =back
501              
502              
503             =head1 ACKNOWLEDGEMENTS
504              
505              
506             =head1 LICENSE AND COPYRIGHT
507              
508             Copyright 2011 Zane C. Bowers-Hadley.
509              
510             This program is free software; you can redistribute it and/or modify it
511             under the terms of either: the GNU General Public License as published
512             by the Free Software Foundation; or the Artistic License.
513              
514             See http://dev.perl.org/licenses/ for more information.
515              
516              
517             =cut
518              
519             1; # End of Wikileaks::AfWD
520