_fetch_record() now sets the temporary value of the
[irspy-moved-to-github.git] / lib / ZOOM / IRSpy / Test / Record / Fetch.pm
1
2 # See the "Main" test package for documentation
3
4 package ZOOM::IRSpy::Test::Record::Fetch;
5
6 use 5.008;
7 use strict;
8 use warnings;
9
10 use ZOOM::IRSpy::Test;
11 our @ISA = qw(ZOOM::IRSpy::Test);
12
13 our $max_timeout_errors = $ZOOM::IRSpy::max_timeout_errors;
14
15 my @queries = (
16                "\@attr 1=4 mineral",
17                "\@attr 1=4 computer",
18                "\@attr 1=44 mineral", # Smithsonian doesn't support AP 4!
19                "\@attr 1=1016 water", # Connector Framework only does 1016
20                ### We can add more queries here
21                );
22
23
24 sub start {
25     my $class = shift();
26     my($conn) = @_;
27
28     $conn->irspy_search_pqf($queries[0], { queryindex => 0 }, {},
29                             ZOOM::Event::ZEND, \&completed_search,
30                             exception => \&completed_search);
31 }
32
33
34 sub completed_search {
35     my($conn, $task, $udata, $event) = @_;
36
37     my $n = $task->{rs}->size();
38     $conn->log("irspy_test", "Fetch test search (", $task->render_query(), ") ",
39                ref $event && $event->isa("ZOOM::Exception") ?
40                "failed: $event" : "found $n records (event=$event)");
41
42     # remember how often a target record hit a timeout
43     if (ref $event && $event->isa("ZOOM::Exception")) {
44         if ($event =~ /Timeout/i) {
45             $conn->record->zoom_error->{TIMEOUT}++;
46             $conn->log("irspy_test", "Increase timeout error counter to: " . 
47                 $conn->record->zoom_error->{TIMEOUT});
48         }
49     }
50
51     if ($n == 0) {
52         $task->{rs}->destroy();
53         my $qindex = $udata->{queryindex}+1;
54         my $q = $queries[$qindex];
55         return ZOOM::IRSpy::Status::TEST_SKIPPED
56             if !defined $q || $conn->record->zoom_error->{TIMEOUT} >= $max_timeout_errors;
57
58         $conn->log("irspy_test", "Trying another search ...");
59         $conn->irspy_search_pqf($queries[$qindex], { queryindex => $qindex }, {},
60                                 ZOOM::Event::ZEND, \&completed_search,
61                                 exception => \&completed_search);
62         return ZOOM::IRSpy::Status::TASK_DONE;
63     }
64
65     my @syntax = (
66                    'canmarc',
67                    'danmarc',
68                    'grs-1',
69                    'ibermarc',
70                    'intermarc',
71                    'jpmarc',
72                    'librismarc',
73                    'mab',
74                    'normarc',
75                    'opac',
76                    'picamarc',
77                    'rusmarc',
78                    'summary',
79                    'sutrs',
80                    'swemarc',
81                    'ukmarc',
82                    'unimarc',
83                    'usmarc',
84                    'xml'
85                 );
86     #@syntax = qw(grs-1 sutrs usmarc xml); # simplify for debugging
87     foreach my $i (0 ..$#syntax) {
88         my $syntax = $syntax[$i];
89         $conn->irspy_rs_record($task->{rs}, 0,
90                                { syntax => $syntax,
91                                  last => ($i == $#syntax) },
92                                { start => 0, count => 1,
93                                  preferredRecordSyntax => $syntax },
94                                 ZOOM::Event::ZEND, \&record,
95                                 exception => \&fetch_error);
96     }
97
98     return ZOOM::IRSpy::Status::TASK_DONE;
99 }
100
101
102 sub record {
103     my($conn, $task, $udata, $event) = @_;
104     my $syn = $udata->{'syntax'};
105     my $rs = $task->{rs};
106
107     my $record = _fetch_record($conn, $rs, 0, $syn);
108     my $ok = 0;
109     if (!$record || $record->error()) {
110         $conn->log("irspy_test", "retrieval of $syn record failed: ",
111                    defined $record ? $record->exception() :
112                                      $conn->exception());
113     } else {
114         $ok = 1;
115         my $text = $record->render();
116         $conn->log("irspy_test", "Successfully retrieved a $syn record");
117         if (0) {
118             print STDERR "Hits: ", $rs->size(), "\n";
119             print STDERR "Syntax: ", $syn, "\n";
120             print STDERR $text;
121         }
122     }
123
124     $conn->record()->store_result('record_fetch',
125                                   'syntax'   => $syn,
126                                   'ok'       => $ok);
127
128     $rs->destroy() if $udata->{last};
129     return ($udata->{last} ?
130             ZOOM::IRSpy::Status::TEST_GOOD :
131             ZOOM::IRSpy::Status::TASK_DONE);
132 }
133
134
135 # By the time this is called, the record has already been physically
136 # fetched from the server in the correct syntax, and placed in the
137 # result-set's cache.  But in order to actually get hold of it from
138 # that cache, we need to set the record-syntax again, to the same
139 # value, otherwise ZOOM will make a fresh request.
140 #
141 # ZOOM::IRSpy::Task::Retrieve sets options into the connection object
142 # rather than the result-set object (because it's a subclass of
143 # ZOOM::IRSpy::Task, which doesn't know about result-sets).  Therefore
144 # it's important that this function also set into the connection:
145 # otherwise any value subsequently set into the connection by
146 # ZOOM::IRSpy::Task::Retrieve will be ignored by ZOOM-C operations, as
147 # the value previously set into the result-set will override it.
148 # (This was the very subtle cause of bug #3534).
149 #
150 sub _fetch_record {
151     my($conn, $rs, $index0, $syntax) = @_;
152
153     my $oldSyntax = $conn->option(preferredRecordSyntax => $syntax);
154     my $record = $rs->record(0);
155     $oldSyntax = "" if !defined $oldSyntax;
156     $conn->option(preferredRecordSyntax => $oldSyntax);
157
158     return $record;
159 }
160
161
162 sub __UNUSED_search_error {
163     my($conn, $task, $test_args, $exception) = @_;
164
165     $conn->log("irspy_test", "Initial search failed: ", $exception);
166     return ZOOM::IRSpy::Status::TEST_SKIPPED;
167 }
168
169
170 sub fetch_error {
171     my($conn, $task, $udata, $exception) = @_;
172     my $syn = $udata->{'syntax'};
173
174     $conn->log("irspy_test", "Retrieval of $syn record failed: ", $exception);
175     $conn->record()->store_result('record_fetch',
176                                   'syntax'       => $syn,
177                                   'ok'        => 0);
178     $task->{rs}->destroy() if $udata->{last};
179     return ZOOM::IRSpy::Status::TASK_DONE;
180 }
181
182
183 1;