File Coverage

blib/lib/ARS/Simple.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 ARS::Simple;
2            
3 1     1   22643 use 5.006;
  1         4  
  1         46  
4 1     1   6 use strict;
  1         1  
  1         44  
5 1     1   6 use warnings FATAL => 'all';
  1         6  
  1         55  
6 1     1   418 use ARS 1.68;
  0            
  0            
7             use Carp;
8             use Data::Dumper;
9            
10             our $VERSION = '0.01';
11            
12             $Data::Dumper::Indent=1;
13             $Data::Dumper::Sortkeys=1;
14            
15             our %config;
16             my $user;
17             my $pword;
18            
19             BEGIN
20             {
21             my $module = 'ARS/Simple.pm';
22             my $cfg = $INC{$module};
23             unless ($cfg)
24             {
25             die "Wrong case in use statement or $module module renamed. Perl is case sensitive!!!\n";
26             }
27             my $compiled = !(-e $cfg); # if the module was not read from disk => the script has been "compiled"
28             $cfg =~ s/\.pm$/.cfg/;
29             if ($compiled or -e $cfg)
30             {
31             # In a Perl2Exe or PerlApp created executable or PerlCtrl
32             # generated COM object or the cfg is known to exist
33             eval {require $cfg};
34             if ($@ and $@ !~ /Can't locate /) #' <-- syntax higlighter
35             {
36             carp "Error in $cfg : $@";
37             }
38             }
39             }
40            
41             sub new
42             {
43             my $proto = shift;
44             my $class = ref($proto) || $proto;
45            
46             my $self = {};
47             bless($self, $class);
48            
49             # Run initialisation code
50             $self->_init(@_);
51            
52             return $self;
53             }
54            
55             sub DESTROY
56             {
57             my $self = shift;
58            
59             if ($self->{ctl})
60             {
61             ars_Logoff($self->{ctl});
62             }
63             }
64            
65             sub _check_initialised
66             {
67             my $self = shift;
68            
69             unless ($self->{ctl})
70             {
71             $self->_carp("Connected to Remedy ARSystem has not been establised yet.\n");
72             return;
73             }
74            
75             return 1;
76             }
77            
78             sub get_list
79             {
80             my ($self, $args) = @_; # Expect args keys of 'form', 'query', optionally 'max_returns'
81            
82             # Check ARSystem initailised
83             return unless $self->_check_initialised();
84            
85             # Check required args
86             unless ($args->{form} && $args->{query})
87             {
88             $self->_carp("get_list() requires 'form' and 'query' arguments\n");
89             return;
90             }
91            
92            
93             # Create a qualifier struct
94             my $qual = $self->_load_qualifier($args);
95             return unless $qual;
96            
97             # Set the limit
98             $self->set_max_entries($args->{max_returns});
99            
100             # Get the entryId
101             my @entries = ars_GetListEntry($self->{ctl}, $args->{form}, $qual, 0, 0,
102             [{columnWidth => 1, separator => ' ', fieldId => 1 }] # Minimise the amount of data returned
103             );
104            
105             # Reset the limit
106             $self->_reset_max_entries();
107            
108            
109             my @entryIds;
110             # Speed hack for large retuns
111             $#entryIds = $#entries;
112             @entryIds = ();
113            
114             for (my $x = 0; $x < $#entries; $x += 2)
115             {
116             #Assign the entryId's to the array, stripping the query list values
117             push @entryIds, $entries[$x];
118             }
119             my %results = ( numMatches => scalar(@entryIds), eids => \@entryIds );
120             return \%results;
121             }
122            
123             sub _load_qualifier
124             {
125            
126             my ($self, $args) = @_;
127            
128             my $qual = ars_LoadQualifier($self->{ctl}, $args->{form}, $args->{query});
129             unless ($qual)
130             {
131             $self->_carp("_load_qualifier() Error processing query:\n$ars_errstr\n");
132             }
133            
134             return $qual;
135             }
136            
137             sub get_data_by_label
138             {
139             my ($self, $args) = @_;
140            
141             my $form = $args->{form};
142             my $query = $args->{query};
143             my $lfid_hr = $args->{lfid};
144             my @fid = values %$lfid_hr;
145            
146             # Check ARSystem initailised
147             return unless $self->_check_initialised();
148            
149             # Check required args
150             unless ($args->{form} && $args->{query})
151             {
152             $self->_carp("get_data_by_label() requires 'form' and 'query' arguments\n");
153             return;
154             }
155            
156             #-- Create a qualifier struct
157             my $qual = $self->_load_qualifier($args);
158             return unless $qual;
159            
160             # Set the limit
161             $self->set_max_entries($args->{max_returns});
162            
163             # Get the data from the form defined by qualifier qual
164             my %entryList;
165             if ($ARS::VERSION >= 1.8)
166             {
167             %entryList = ars_GetListEntryWithFields($self->{ctl}, $form, $qual, 0, 0, \@fid);
168             }
169             else
170             {
171             %entryList = ars_GetListEntryWithFields($self->{ctl}, $form, $qual, 0, \@fid);
172             }
173            
174             # Reset the limit
175             $self->_reset_max_entries();
176            
177             unless (%entryList)
178             {
179             no warnings qw(uninitialized);
180             if ($ars_errstr)
181             {
182             $self->_carp("get_data_by_label() failed.\nError=$ars_errstr\nForm=$form\nQuery=$query\n");
183             }
184             else
185             {
186             if ($self->{log})
187             {
188             $self->{log}->msg(3, "get_data_by_label() no records found.\n");
189             }
190             }
191             return;
192             }
193            
194             # Map the FID's to Labels in the hashs
195             my %fid2label = reverse %$lfid_hr;
196             foreach my $eID (keys %entryList)
197             {
198             foreach my $fid (keys %{$entryList{$eID}})
199             {
200             if (defined $fid2label{$fid})
201             {
202             $entryList{$eID}{$fid2label{$fid}} = $entryList{$eID}{$fid};
203             delete $entryList{$eID}{$fid};
204             }
205             }
206             }
207            
208             return \%entryList;
209             }
210            
211             sub get_SQL
212             {
213             my ($self, $args) = @_;
214            
215             # Set the limit
216             $self->set_max_entries($args->{max_returns});
217            
218             # Run the SQL through the ARSystem API
219             my $m = ars_GetListSQL($self->{ctl}, $self->{sql});
220            
221             # Reset the limit
222             $self->_reset_max_entries();
223            
224             # $m = {
225             # "numMatches" => integer,
226             # "rows" => [ [r1col1, r1col2], [r2col1, r2col2] ... ],
227             # }
228             if ($ars_errstr && $ars_errstr ne '')
229             {
230             $self->_carp('get_SQL() - ars_GetListSQL error, sql=', $self->{sql}, "\nars_errstr=$ars_errstr\n");
231             }
232            
233             return $m;
234             }
235            
236             sub set_max_entries
237             {
238             my ($self, $max) = @_;
239            
240             if (defined $max)
241             {
242             # Just use the value given
243             }
244             elsif ($self->{max_returns})
245             {
246             $max = $self->{max_returns};
247             }
248             elsif (defined $self->{reset_limit})
249             {
250             $max = 0; # Set for unlimited returns if we have a reset limit defined
251             }
252            
253             if (defined $max)
254             {
255             unless(ars_SetServerInfo($self->{ctl}, &ARS::AR_SERVER_INFO_MAX_ENTRIES, $max))
256             {
257             $self->_carp("set_max_entries() - Could not set the AR_SERVER_INFO_MAX_ENTRIES to $max:\n$ars_errstr\n");
258             }
259             }
260             }
261            
262             sub _reset_max_entries
263             {
264             my $self = shift;
265            
266             if (defined $self->{reset_limit})
267             {
268             $self->set_max_entries($self->{reset_limit});
269             }
270             }
271            
272             sub get_fields
273             {
274             my ($self, $form) = @_;
275            
276             # Check required args
277             unless ($form)
278             {
279             $self->_carp("get_fields() requires the 'form' as a argument\n");
280             return;
281             }
282            
283             my %fids = ars_GetFieldTable($self->{ctl}, $form);
284             $self->_carp("get_fields() error: $ars_errstr\n") unless (%fids);
285            
286             return \%fids;
287             }
288            
289             sub update_record
290             {
291             my ($self, $args) = @_;
292             my $eID = $args->{eid};
293             my $form = $args->{form};
294             my %lvp = %{$args->{lvp}};
295            
296            
297             # Map lvp to use FID rather than label
298             foreach my $label (keys %lvp)
299             {
300             if (defined $args->{lvp}{$label})
301             {
302             $lvp{$args->{lfid}{$label}} = $lvp{$label};
303             delete $lvp{$label};
304             }
305             else
306             {
307             carp("update_record - label '$label' not found in lfid hash");
308             }
309             }
310            
311            
312             my $rv = ars_SetEntry($self->{ctl}, $form, $eID, 0, %lvp);
313            
314             # Check for errors
315             unless (defined $rv && $rv == 1)
316             {
317             # Update failed
318             my $msg = "update_record(eid=$eID, form=$form, ...) failed:\nars_errstr=$ars_errstr\nlvp data was:\n";
319             foreach my $label (sort keys %{$args->{lvp}})
320             {
321             $msg .= sprintf("%30s (%10d) ---> %s\n", $label, $args->{lfid}{$label}, defined($lvp{$args->{lfid}{$label}}) ? $lvp{$args->{lfid}{$label}} : '');
322             }
323             carp($msg);
324             }
325             return $rv;
326             }
327            
328             sub get_ctl
329             {
330             my $self = shift;
331            
332             return $self->{ctl};
333             }
334            
335             sub _carp
336             {
337             my $self = shift;
338             my $msg = join('', @_);
339            
340             carp $msg;
341             $self->{log}->exp($msg) if ($self->{log});
342             }
343            
344             sub _init
345             {
346             my ($self, $args) = @_;
347            
348             # Did we have any of the persistant variables passed
349             my $k = '5Jv@sI9^bl@D*j5H3@:7g4H[2]d%Ks314aNuGeX;';
350             if ($args->{user})
351             {
352             $self->{persistant}{user} = $args->{user};
353             }
354             else
355             {
356             if (defined $config{user})
357             {
358             my $s = pack('H*', $config{user});
359             my $x = substr($k, 0, length($s));
360             my $u = $s ^ $x;
361             $self->{persistant}{user} = $u;
362             }
363             else
364             {
365             croak "No user defined, quitting\n";
366             }
367             }
368            
369             if ($args->{password})
370             {
371             $self->{persistant}{password} = $args->{password};
372             }
373             else
374             {
375             if (defined $config{password})
376             {
377             my $s = pack('H*', $config{password});
378             my $x = substr($k, 0, length($s));
379             my $u = $s ^ $x;
380             $self->{persistant}{password} = $u;
381             }
382             else
383             {
384             croak "No password defined, quitting\n";
385             }
386             }
387             $user = $self->{persistant}{user};
388             $pword = $self->{persistant}{password};
389            
390             # Handle the other passed arguments
391             $self->{server} = $args->{server} if $args->{server};
392             $self->{log} = $args->{log} if $args->{log};
393             $self->{max_returns} = $args->{max_returns} if defined $args->{max_returns};
394             $self->{reset_limit} = $args->{reset_limit} if defined $args->{reset_limit};
395            
396             if ($args->{ars_debug})
397             {
398             $ARS::DEBUGGING = 1;
399             }
400             $self->{debug} = $args->{debug} ? 1 : 0;
401            
402             ## Now connect to Remedy
403             if ($self->{server} && $user && $pword)
404             {
405             my $ctl = ars_Login($self->{server}, $user, $pword);
406             if ($ctl)
407             {
408             $self->{ctl} = $ctl;
409             }
410             else
411             {
412             croak(__PACKAGE__ . " object initialisation failed.\nFailed to log into Remedy server=" . $self->{server} . " as user '$user' with supplied password: $ars_errstr\n");
413             }
414             }
415             else
416             {
417             croak(__PACKAGE__ . " object initialisation failed, server, user and password are required\n");
418             }
419             }
420            
421            
422             # GG test - need to find and store the current value of AR_SERVER_INFO_MAX_ENTRIES
423             # so we can set reset_limit if not defined
424             #my %s = ars_GetServerInfo($self->{ctl});
425             #print Dumper(\%s);
426            
427            
428             1; # End of ARS::Simple
429            
430            
431             __END__