DataFax/StudySubs.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 13 | 15 | 86.6 |
branch | n/a | ||
condition | n/a | ||
subroutine | 5 | 5 | 100.0 |
pod | n/a | ||
total | 18 | 20 | 90.0 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package DataFax::StudySubs; | ||||||
2 | |||||||
3 | 1 | 1 | 38655 | use strict; | |||
1 | 2 | ||||||
1 | 448 | ||||||
4 | 1 | 1 | 7 | use vars qw(@ISA $VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS); | |||
1 | 2 | ||||||
1 | 304 | ||||||
5 | 1 | 1 | 7 | use Carp; | |||
1 | 7 | ||||||
1 | 94 | ||||||
6 | 1 | 1 | 3187 | use IO::File; | |||
1 | 14849 | ||||||
1 | 125 | ||||||
7 | 1 | 1 | 1584 | use Net::Rexec 'rexec'; | |||
0 | |||||||
0 | |||||||
8 | |||||||
9 | $VERSION = 0.10; | ||||||
10 | use DataFax; | ||||||
11 | @ISA = qw(Exporter DataFax); | ||||||
12 | @EXPORT = qw(dfparam disp_param debug_level echo_msg get_dfparam); | ||||||
13 | @EXPORT_OK = qw(dfparam disp_param debug_level echo_msg get_dfparam | ||||||
14 | exec_cmd | ||||||
15 | ); | ||||||
16 | %EXPORT_TAGS= ( | ||||||
17 | all =>[@EXPORT_OK], | ||||||
18 | echo_msg=>[qw(dfparam disp_param debug_level echo_msg get_dfparam)], | ||||||
19 | param =>[qw(dfparam disp_param get_dfparam)], | ||||||
20 | cmd =>[qw(exec_cmd)], | ||||||
21 | ); | ||||||
22 | |||||||
23 | =head1 NAME | ||||||
24 | |||||||
25 | DataFax::StudySubs - DataFax common sub routines | ||||||
26 | |||||||
27 | =head1 SYNOPSIS | ||||||
28 | |||||||
29 | use DataFax::StudySubs qw(:all); | ||||||
30 | |||||||
31 | =head1 DESCRIPTION | ||||||
32 | |||||||
33 | This class contains the common sub-routines used in DataFax. | ||||||
34 | |||||||
35 | =cut | ||||||
36 | |||||||
37 | sub new { | ||||||
38 | my ($s, %args) = @_; | ||||||
39 | return $s->SUPER::new(%args); | ||||||
40 | } | ||||||
41 | |||||||
42 | # --------------------------------------------------------------------- | ||||||
43 | |||||||
44 | =head1 Export Tag: all | ||||||
45 | |||||||
46 | The :all tag includes the all the methods in this module. | ||||||
47 | |||||||
48 | use DataFax::StudySubs qw(:all); | ||||||
49 | |||||||
50 | It includes the following sub-routines: | ||||||
51 | |||||||
52 | =head2 dfparam($var, $ar[,$val]) | ||||||
53 | |||||||
54 | Input variables: | ||||||
55 | |||||||
56 | $var - variable name | ||||||
57 | $ar - parameter hash or array ref | ||||||
58 | $val - value to be added or assigned | ||||||
59 | |||||||
60 | Variables used or routines called: | ||||||
61 | |||||||
62 | None | ||||||
63 | |||||||
64 | How to use: | ||||||
65 | |||||||
66 | use DataFax::DFstudyDB qw(dfparam); | ||||||
67 | my $ar = {a=>1,b=>25}; | ||||||
68 | my $br = [1,2,5,10]; | ||||||
69 | # for hash ref | ||||||
70 | my $va = $self->dfparam('a',$ar); # set $va = 1 | ||||||
71 | my $v1 = $self->dfparam('v1',$ar); # set $v1 = "" | ||||||
72 | my $v2 = $self->dfparam('b',$ar); # set $v2 = 25 | ||||||
73 | # for array ref | ||||||
74 | my $v3 = $self->dfparam(0,$br); # set $v3 = 1 | ||||||
75 | my $v4 = $self->dfparam(3,$br); # set $v4 = 10 | ||||||
76 | # add or assign values and return array ref | ||||||
77 | $self->dfparam('c',$ar,30); # set $ar->{c} = 30 | ||||||
78 | $self->dfparam(5,$br,50); # set $br->[5] = 50 | ||||||
79 | |||||||
80 | Return: $r - the value in the hash or empty string or array ref. | ||||||
81 | |||||||
82 | This method gets and sets the $var in $ar. If the varirable | ||||||
83 | does not exists in $ar, it tries in $self as well for 'get'. | ||||||
84 | |||||||
85 | =cut | ||||||
86 | |||||||
87 | sub dfparam { | ||||||
88 | my ($s, $v, $r) = @_; | ||||||
89 | if ($#_>2) { # there is a third input | ||||||
90 | $r->[$v] = $_[3] if $v =~ /^\d+$/ && ref($r) =~ /ARRAY/; | ||||||
91 | $r->{$v} = $_[3] if ref($r) =~ /HASH/ || ref $r; | ||||||
92 | return ; | ||||||
93 | } | ||||||
94 | # if only variable name and the name exists in the class object | ||||||
95 | return $s->{$v} if $#_==1 && exists $s->{$v}; | ||||||
96 | # return blank if no $v or $r is not array, hash nor object | ||||||
97 | return "" if $v =~ /^\s*$/; | ||||||
98 | return $s->{$v} if exists $s->{$v} && !$r; | ||||||
99 | return "" if ! ref($r); | ||||||
100 | return "" if $v !~ /^\d+$/ && ref($r) =~ /ARRAY/; | ||||||
101 | |||||||
102 | return (exists $r->[$v])?$r->[$v]:"" if ref($r) =~ /^ARRAY/; | ||||||
103 | # if $r = $s, then ref $r will make it sure to catch that as well | ||||||
104 | return (exists $r->{$v})?$r->{$v}:((exists $s->{$v})?$s->{$v}:"") | ||||||
105 | if ref($r) =~ /^HASH/ || ref $r; | ||||||
106 | return ""; # catch all | ||||||
107 | } | ||||||
108 | |||||||
109 | =head2 get_dfparam($vs, $ar) | ||||||
110 | |||||||
111 | Input variables: | ||||||
112 | |||||||
113 | $vs - a list of variable names separated by comma | ||||||
114 | $ar - parameter hash or array ref | ||||||
115 | |||||||
116 | Variables used or routines called: | ||||||
117 | |||||||
118 | dfparam - get individual parameter | ||||||
119 | |||||||
120 | How to use: | ||||||
121 | |||||||
122 | use DataFax::DFstudyDB qw(:all); | ||||||
123 | my $ar = {a=>1,b=>25}; | ||||||
124 | my ($va, $vb) = $self->get_dfparam('a,b',$ar); | ||||||
125 | |||||||
126 | Return: array or array ref | ||||||
127 | |||||||
128 | This method gets multiple values for listed variables. | ||||||
129 | |||||||
130 | =cut | ||||||
131 | |||||||
132 | sub get_dfparam { | ||||||
133 | my $s = shift; | ||||||
134 | my ($vs, $r) = @_; | ||||||
135 | return () if ! $vs; | ||||||
136 | my $p = []; | ||||||
137 | $vs =~ s/\s+//g; # remove any spaces | ||||||
138 | foreach my $k (split /,/, $vs) { | ||||||
139 | push @$p, $s->dfparam($k, $r); | ||||||
140 | } | ||||||
141 | return wantarray ? @$p : $p; | ||||||
142 | } | ||||||
143 | |||||||
144 | =head2 exec_cmd ($cmd, $pr) | ||||||
145 | |||||||
146 | Input variables: | ||||||
147 | |||||||
148 | $cmd - a full unix command with paraemters and arguments | ||||||
149 | $pr - parameter hash ref | ||||||
150 | datafax_host - DataFax host name or ip address | ||||||
151 | local_host - local host name or ip address | ||||||
152 | datafax_usr - DataFax user name | ||||||
153 | datafax_pwd - DataFax user password | ||||||
154 | |||||||
155 | Variables used or routines called: | ||||||
156 | |||||||
157 | get_dfparam - get values for multiple parameters | ||||||
158 | |||||||
159 | How to use: | ||||||
160 | |||||||
161 | use DataFax::DFstudyDB qw(:all); | ||||||
162 | # Case 1: hosts are different and without id and password | ||||||
163 | my $cmd = "cat /my/dir/file.txt"; | ||||||
164 | my $pr = {datafax_host=>'dfsvr',local_host='svr2'}; | ||||||
165 | my @a = $self->exec_cmd($cmd,$pr); # uses rsh to run the cmd | ||||||
166 | |||||||
167 | # Case 2: different hosts with id and password | ||||||
168 | my $pr = {datafax_host=>'dfsvr',local_host='svr2', | ||||||
169 | datafax_usr=>'fusr', datafax_pwd=>'pwd' }; | ||||||
170 | my @a = $self->exec_cmd($cmd,$pr); # uses rexec | ||||||
171 | |||||||
172 | # Case 2: hosts are the same | ||||||
173 | my $pr = {datafax_host=>'dfsvr',local_host='dfsvr'}; | ||||||
174 | my $ar = $self->exec_cmd('/my/file.txt',$pr); # case 2: | ||||||
175 | |||||||
176 | Return: array or array ref | ||||||
177 | |||||||
178 | This method opens a file or runs a command and return the contents | ||||||
179 | in array or array ref. | ||||||
180 | |||||||
181 | =cut | ||||||
182 | |||||||
183 | sub exec_cmd { | ||||||
184 | my $s = shift; | ||||||
185 | my ($cmd, $pr) = @_; | ||||||
186 | my $vs='datafax_host,local_host,datafax_usr,datafax_pwd'; | ||||||
187 | my ($dfh,$lsv,$usr,$pwd) = $s->get_dfparam($vs,$pr); | ||||||
188 | $lsv = `hostname` if ! $lsv; | ||||||
189 | my ($rc, @a); | ||||||
190 | if ($dfh ne $lsv) { | ||||||
191 | # croak "ERR: no user name for remote access.\n" if ! $usr; | ||||||
192 | # croak "ERR: no password for user $usr.\n" if ! $pwd; | ||||||
193 | if ($usr && $pwd) { # use rexec | ||||||
194 | $s->echo_msg(" CMD: $cmd at $dfh for user $usr...", 1); | ||||||
195 | ($rc, @a) = rexec($dfh, $cmd, $usr, $pwd); | ||||||
196 | $rc == 0 || carp " WARN: could not run $cmd on $dfh.\n"; | ||||||
197 | } else { # use rsh | ||||||
198 | my $u = "rsh $dfh $cmd |"; | ||||||
199 | my $fh = new IO::File; | ||||||
200 | $fh->open("$u")||carp " WARN: could not run $u: $!.\n"; | ||||||
201 | @a=<$fh>; close($fh); | ||||||
202 | } | ||||||
203 | } else { # use perl module | ||||||
204 | $s->echo_msg(" CMD: $cmd at $lsv...", 1); | ||||||
205 | my $fh = new IO::File; | ||||||
206 | $fh->open("$cmd") || carp " WARN: could not run $cmd: $!.\n"; | ||||||
207 | @a=<$fh>; close($fh); | ||||||
208 | } | ||||||
209 | return wantarray ? @a : \@a; | ||||||
210 | } | ||||||
211 | |||||||
212 | =head2 debug_level($n) | ||||||
213 | |||||||
214 | Input variables: | ||||||
215 | |||||||
216 | $n - a number between 0 and 100. It specifies the | ||||||
217 | level of messages that you would like to | ||||||
218 | display. The higher the number, the more | ||||||
219 | detailed messages that you will get. | ||||||
220 | |||||||
221 | Variables used or routines called: None. | ||||||
222 | |||||||
223 | How to use: | ||||||
224 | |||||||
225 | $self->debug_level(2); # set the message level to 2 | ||||||
226 | print $self->debug_level; # print current message level | ||||||
227 | |||||||
228 | Return: the debug level or set the debug level. | ||||||
229 | |||||||
230 | =cut | ||||||
231 | |||||||
232 | sub debug_level { | ||||||
233 | # my ($c_pkg,$c_fn,$c_ln) = caller; | ||||||
234 | # my $s = ref($_[0])?shift:(bless {}, $c_pkg); | ||||||
235 | my $s = shift; | ||||||
236 | croak "ERR: Too many args to debug." if @_ > 1; | ||||||
237 | @_ ? ($s->{_debug_level}=shift) : return $s->{_debug_level}; | ||||||
238 | } | ||||||
239 | |||||||
240 | =head2 echo_msg($msg, $lvl, $fh) | ||||||
241 | |||||||
242 | Input variables: | ||||||
243 | |||||||
244 | $msg - the message to be displayed. No newline | ||||||
245 | is needed in the end of the message. It | ||||||
246 | will add the newline code at the end of | ||||||
247 | the message. | ||||||
248 | $lvl - the message level is assigned to the message. | ||||||
249 | If it is higher than the debug level, then | ||||||
250 | the message will not be displayed. | ||||||
251 | $fh - file handler, or set the file hanlder in this parameter | ||||||
252 | $ENV{FH_DEBUG_LOG} | ||||||
253 | |||||||
254 | Variables used or routines called: | ||||||
255 | |||||||
256 | debug_level - get debug level. | ||||||
257 | |||||||
258 | How to use: | ||||||
259 | |||||||
260 | # default msg level to 0 | ||||||
261 | $self->echo_msg('This is a test"); | ||||||
262 | # set the msg level to 2 | ||||||
263 | $self->echo_msg('This is a test", 2); | ||||||
264 | |||||||
265 | Return: None. | ||||||
266 | |||||||
267 | This method will display message or a hash array based on I |
||||||
268 | level. If I |
||||||
269 | displayed. If I |
||||||
270 | level ($lvl) is less than or equal to '2'. If you call this | ||||||
271 | method without providing a message level, the message level ($lvl) is | ||||||
272 | default to '0'. Of course, if no message is provided to the method, | ||||||
273 | it will be quietly returned. | ||||||
274 | |||||||
275 | This is how you can call I |
||||||
276 | |||||||
277 | my $df = DataFax->new; | ||||||
278 | $df->echo_msg("This is a test"); # default the msg to level 0 | ||||||
279 | $df->echo_msg("This is a test",1); # assign the msg as level 1 msg | ||||||
280 | $df->echo_msg("Test again",2); # assign the msg as level 2 msg | ||||||
281 | $df->echo_msg($hrf,1); # assign $hrf as level 1 msg | ||||||
282 | $df->echo_msg($hrf,2); # assign $hrf as level 2 msg | ||||||
283 | |||||||
284 | If I |
||||||
285 | i.e., 0, and '1' will be displayed. The higher level messages | ||||||
286 | will not be displayed. | ||||||
287 | |||||||
288 | This method displays or writes the message based on debug level. | ||||||
289 | The filehandler is provided through $fh or $ENV{FH_DEBUG_LOG}, and | ||||||
290 | the outputs are written to the file. | ||||||
291 | |||||||
292 | =cut | ||||||
293 | |||||||
294 | sub echo_msg { | ||||||
295 | # my ($c_pkg,$c_fn,$c_ln) = caller; | ||||||
296 | # my $self = ref($_[0])?shift:(bless {},$c_pkg); | ||||||
297 | my $self = shift; | ||||||
298 | my ($msg,$lvl, $fh) = @_; | ||||||
299 | $fh = (exists $ENV{FH_DEBUG_LOG})?$ENV{FH_DEBUG_LOG}:""; | ||||||
300 | $fh = "" if !$fh || ($fh && ref($fh) !~ /(IO::File|GLOB)/); | ||||||
301 | if (!defined($msg)) { return; } # return if no msg | ||||||
302 | if (!defined($lvl)) { $lvl = 0; } # default level to 0 | ||||||
303 | my $class = ref($self)||$self; # get class name | ||||||
304 | my $dbg = $self->debug_level; # get debug level | ||||||
305 | if (!$dbg) { return; } # return if not debug | ||||||
306 | my $ref = ref($msg); | ||||||
307 | if ($ref eq $class || $ref =~ /(ARRAY|HASH)/) { | ||||||
308 | if ($lvl <= $dbg) { $self->disp_param($msg); } | ||||||
309 | } else { | ||||||
310 | $msg = "$msg" if exists $ENV{QUERY_STRING} && |
||||||
311 | $msg =~ /^\s*\d+\.\s+\w+/; | ||||||
312 | $msg =~ s/\/(\w+)\@/\/****\@/g if $msg =~ /(\w+)\/(\w+)\@(\w+)/; | ||||||
313 | $msg = "$msg\n"; | ||||||
314 | $msg =~ s/\n/ \n/gm if exists $ENV{QUERY_STRING}; |
||||||
315 | if ($lvl <= $dbg) { | ||||||
316 | if ($fh) { print $fh $msg; } else { print $msg; } | ||||||
317 | } | ||||||
318 | } | ||||||
319 | } | ||||||
320 | |||||||
321 | =head2 disp_param($arf,$lzp, $fh) | ||||||
322 | |||||||
323 | Input variables: | ||||||
324 | |||||||
325 | $arf - array reference | ||||||
326 | $lzp - number of blank space indented in left | ||||||
327 | $fh - file handler | ||||||
328 | |||||||
329 | Variables used or routines called: | ||||||
330 | |||||||
331 | echo_msg - print debug messages | ||||||
332 | debug_level - set debug level | ||||||
333 | disp_param - recusively called | ||||||
334 | |||||||
335 | How to use: | ||||||
336 | |||||||
337 | use DataFax::StudySubs qw(:echo_msg); | ||||||
338 | my $self= bless {}, "main"; | ||||||
339 | $self->disp_param($arf); | ||||||
340 | |||||||
341 | Return: Display the content of the array. | ||||||
342 | |||||||
343 | This method recursively displays the contents of an array. If a | ||||||
344 | filehandler is provided through $fh or $ENV{FH_DEBUG_LOG}, the outputs | ||||||
345 | are written to the file. | ||||||
346 | |||||||
347 | =cut | ||||||
348 | |||||||
349 | sub disp_param { | ||||||
350 | my ($self, $hrf, $lzp, $fh) = @_; | ||||||
351 | my $otp = ref $hrf; | ||||||
352 | $self->echo_msg(" - displaying parameters in $otp..."); | ||||||
353 | $fh = (exists $ENV{FH_DEBUG_LOG})?$ENV{FH_DEBUG_LOG}:""; | ||||||
354 | $fh = "" if !$fh || ($fh && ref($fh) !~ /(IO::File|GLOB)/); | ||||||
355 | if (!$lzp) { $lzp = 15; } else { $lzp +=4; } | ||||||
356 | my $fmt; | ||||||
357 | if (exists $ENV{QUERY_STRING}) { | ||||||
358 | # $fmt = "%${lzp}s = %-30s \n"; |
||||||
359 | $fmt = (" " x $lzp) . "%s = %-30s \n"; |
||||||
360 | } else { | ||||||
361 | $fmt = "%${lzp}s = %-30s\n"; | ||||||
362 | } | ||||||
363 | if (!$hrf) { | ||||||
364 | print "Please specify an array ref.\n"; | ||||||
365 | return; | ||||||
366 | } | ||||||
367 | # print join "|", $self, "HRF", $hrf, ref($hrf), "\n"; | ||||||
368 | my ($v); | ||||||
369 | if (ref($hrf) eq 'HASH'|| $hrf =~ /.*=HASH/) { | ||||||
370 | foreach my $k (sort keys %{$hrf}) { | ||||||
371 | if (!defined(${$hrf}{$k})) { $v = ""; | ||||||
372 | } else { $v = ${$hrf}{$k}; } | ||||||
373 | if ($v =~ /([-\w_]+)\/(\w+)\@(\w+)/) { | ||||||
374 | $v =~ s{(\w+)/(\w+)\@}{$1/\*\*\*\@}g; | ||||||
375 | } | ||||||
376 | chomp $v; | ||||||
377 | if ($fh) { printf $fh $fmt, $k, $v; | ||||||
378 | } else { printf $fmt, $k, $v; } | ||||||
379 | if (ref($v) =~ /^(HASH|ARRAY)$/ || | ||||||
380 | $v =~ /.*=(HASH|ARRAY)/) { | ||||||
381 | my $db1 = $self->debug_level; | ||||||
382 | $self->debug_level(0); | ||||||
383 | # print "$k = ${$hrf}{$k}: @{${$hrf}{$k}}\n"; | ||||||
384 | $self->disp_param(${$hrf}{$k},$lzp); | ||||||
385 | $self->debug_level($db1); | ||||||
386 | if ($fh) { print $fh "\n"; } else { print "\n"; } | ||||||
387 | } | ||||||
388 | } | ||||||
389 | } elsif (ref($hrf) eq 'ARRAY' || $hrf =~ /.*=ARRAY/) { | ||||||
390 | foreach my $i (0..$#{$hrf}) { | ||||||
391 | if (!defined(${$hrf}[$i])) { $v = ""; | ||||||
392 | } else { $v = ${$hrf}[$i]; } | ||||||
393 | if ($v =~ /([-\w_]+)\/(\w+)\@(\w+)/) { | ||||||
394 | $v =~ s{(\w+)/(\w+)\@}{$1/\*\*\*\@}g; | ||||||
395 | } | ||||||
396 | chomp $v; | ||||||
397 | if ($fh) { printf $fh $fmt, $i, $v; | ||||||
398 | } else { printf $fmt, $i, $v; } | ||||||
399 | if (ref($v) =~ /^(HASH|ARRAY)$/ || | ||||||
400 | $v =~ /.*=(HASH|ARRAY)/) { | ||||||
401 | my $db1 = $self->debug_level; | ||||||
402 | $self->debug_level(0); | ||||||
403 | $self->disp_param(${$hrf}[$i],$lzp); | ||||||
404 | $self->debug_level($db1); | ||||||
405 | if ($fh) { print $fh "\n"; } else { print "\n"; } | ||||||
406 | } | ||||||
407 | } | ||||||
408 | } | ||||||
409 | } | ||||||
410 | |||||||
411 | 1; | ||||||
412 |