15 # Running as root, switch privs
17 open PID, ">/var/run/processz3950queue.pid";
21 # Get real apacheuser from koha.conf or reparsing httpd.conf
22 my $apacheuser=C4::Context->config("httpduser");
24 unless ($uid = (getpwnam($apacheuser))[2]) {
25 die "Attempt to run daemon as non-existent or superuser\n";
30 my $dbh = C4::Context->dbh;
32 my $sth=$dbh->prepare("update z3950results set active=0");
36 $SIG{HUP}='checkqueue';
41 open PID, ">$logdir/processz3950queue.pid";
51 if ((time-$lastrun)>5) {
52 print "starting loop\n";
53 $checkqueue = 1; # FIXME during testing, this line forces the loop. REMOVE it to use SIG{HUP} when "daemonized" !
54 if ($checkqueue) { # everytime a SIG{HUP} is recieved
56 my $sth=$dbh->prepare("select id,term,type,servers,identifier from z3950queue order by id");
58 while (my ($id, $term, $type, $servers,$random) = $sth->fetchrow) {
59 if ($forkcounter<12) {
61 my $stk=$dbh->prepare("select id,server,startdate,enddate,numrecords,active from z3950results where queryid=?");
62 ($stk->execute($id)) || (next);
65 my $sti=$dbh->prepare("update z3950queue set done=-1,startdate=? where id=?");
66 $sti->execute($now,$id);
68 while (my ($r_id, $r_server,$r_startdate,$r_enddate,$r_numrecords,$active) = $stk->fetchrow) {
70 $serverdone{$r_server}=1;
72 $serverdone{$r_server}=1;
74 $serverdone{$r_server}=-1;
80 if ($type eq 'isbn') {
82 } elsif ($type eq 'title') {
84 } elsif ($type eq 'author') {
86 } elsif ($type eq 'lccn') {
88 } elsif ($type eq 'keyword') {
92 my $query="\@attr $attr $term";
95 my $stillprocessing=0;
99 foreach $serverinfo (split(/\|/, $servers)) {
100 (next) if ($serverdone{$serverinfo} == 1);
101 my $stillprocessing=1;
102 if (my $pid=fork()) {
105 my $dbi = C4::Context->dbh;
106 my ($name, $server, $database, $user, $password,$syntax) = split(/\//, $serverinfo, 6);
108 $globalsyntax = $syntax;
109 $server=~/(.*)\:(\d+)/;
112 print "Processing $type=$term at $name $server $database $syntax (".($forkcounter+1)." forks)\n";
114 my $q_serverinfo=$dbi->quote($serverinfo);
116 if ($serverdone{$serverinfo}==-1) {
117 my $stj=$dbi->prepare("select id from z3950results where server=? and queryid=?");
118 $stj->execute($q_serverinfo,$id);
119 ($resultsid) = $stj->fetchrow;
122 my $stj=$dbi->prepare("select id from z3950results where server=? and queryid=?");
123 $stj->execute($q_serverinfo,$id);
124 ($resultsid) = $stj->fetchrow;
126 unless ($resultsid) {
127 $stj=$dbi->prepare("insert into z3950results (server, queryid, startdate) values (?,?,?)");
128 $stj->execute($q_serverinfo, $id, $now);
129 $resultsid=$dbi->{'mysql_insertid'};
133 my $stj=$dbh->prepare("update z3950results set active=1 where id=?");
134 $stj->execute($resultsid);
139 eval { $conn= new Net::Z3950::Connection($servername, $port, databaseName => $database, user => $user, password => $password); };
146 eval { $conn= new Net::Z3950::Connection($servername, $port, databaseName => $database); };
153 if ($noconnection || $error) {
154 warn "no connection at $globalname ";
156 warn "$globalname ==> $globalsyntax";
157 eval {$conn->option(elementSetName => 'F')};
158 eval { $conn->option(preferredRecordSyntax => Net::Z3950::RecordSyntax::USMARC);} if ($globalsyntax eq "USMARC");
159 eval { $conn->option(preferredRecordSyntax => Net::Z3950::RecordSyntax::UNIMARC);} if ($globalsyntax eq "UNIMARC");
161 print "$globalname ERROR: $@\n";
163 # print "Q: $query\n";
164 my $rs=$conn->search($query);
166 my $numresults=$rs->size();
167 if ($numresults eq 0) {
168 warn "$globalname ==> answered : no records found";
170 warn "$globalname ==> answered : $numresults found";
175 my $scantimerstart=time();
176 for ($i=1; $i<=(($numresults<80) ? ($numresults) : (80)); $i++) {
177 my $rec=$rs->record($i);
179 # use render() or rawdata() depending on the type of the returned record
181 if (ref($rec) eq "Net::Z3950::Record::USMARC") {
182 $marcdata = $rec->rawdata();
183 $marcrecord = MARC::File::USMARC::decode($rec->rawdata())
185 if (ref($rec) eq "Net::Z3950::Record::UNIMARC") {
186 $marcdata = $rec->render();
187 $marcrecord = MARC::File::USMARC::decode($rec->render())
189 $globalencoding = ref($rec);
192 my @x=split /::/,$globalencoding;
193 my ($notmarcrecord,$alreadyindb,$alreadyinfarm,$imported) = ImportBreeding($result,-1,"Z3950-$globalname",$x[3],$random);
194 my $scantimerend=time();
196 ($numresults<80) ? ($numrecords=$numresults) : ($numrecords=80);
197 my $elapsed=$scantimerend-$scantimerstart;
199 my $speed=int($numresults/$elapsed*100)/100;
200 print "$globalname SPEED: $speed $server done $numrecords\n";
202 my $q_result=$dbi->quote($result);
203 ($q_result) || ($q_result='""');
205 if ($numresults >0) {
206 my $stj=$dbi->prepare("update z3950results set numrecords=?,numdownloaded=?,highestseen=0,results=?,enddate=? where id=?");
207 $stj->execute($numresults,$numrecords,$q_result,$now,$resultsid);
208 } else { # no results...
209 my $stj=$dbi->prepare("update z3950results set numrecords=?,numdownloaded=?,highestseen=0,results='',enddate=? where id=?");
210 $stj->execute($numresults,$numrecords,$now,$resultsid);
213 while ($counter<60 && $numrecords<$numresults) {
215 my $stj=$dbi->prepare("select highestseen from z3950results where id=?");
216 $stj->execute($resultsid);
217 my ($highestseen) = $stj->fetchrow;
218 if ($highestseen>($numrecords-30)) {
220 print " $server rescanning\n";
221 my $scantimerstart=time();
222 for ($i=$numrecords+1; $i<=(($numresults<($numrecords+40)) ? ($numresults) : ($numrecords+40)); $i++) {
223 my $rec=$rs->record($i);
224 my $marcdata=$rec->rawdata();
227 my $scantimerend=time();
228 ($numresults<$numrecords+40) ? ($numrecords=$numresults) : ($numrecords += 40);
229 my $elapsed=$scantimerend-$scantimerstart;
231 my $speed=int($numresults/$elapsed*100)/100;
232 print " SPEED: $speed $server done $numrecords\n";
235 my $q_result=$dbi->quote($result);
236 ($q_result) || ($q_result='""');
238 my $stj=$dbi->prepare("update z3950results set numdownloaded=?,results=? where id=?");
239 $stj->execute($numrecords,$q_result,$resultsid);
245 # FIXME - There's already a $stj in this scope
246 my $stj=$dbi->prepare("update z3950results set active=0 where id=?");
247 $stj->execute($resultsid);
249 print " $server done.\n";
253 my $code=$conn->errcode();
254 my $msg=$conn->errmsg();
255 my $ai=$conn->addinfo();
265 unless ($stillprocessing) {
266 #my $sti=$dbh->prepare("select enddate from z3950queue where id=?");
268 #my ($enddate) = $sti->fetchrow;