View | Details | Raw Unified | Return to bug 7440
Collapse All | Expand All

(-)a/C4/Auth.pm (-1 lines)
Lines 362-368 sub get_template_and_user { Link Here
362
            suggestion                  => C4::Context->preference("suggestion"),
362
            suggestion                  => C4::Context->preference("suggestion"),
363
            virtualshelves              => C4::Context->preference("virtualshelves"),
363
            virtualshelves              => C4::Context->preference("virtualshelves"),
364
            StaffSerialIssueDisplayCount => C4::Context->preference("StaffSerialIssueDisplayCount"),
364
            StaffSerialIssueDisplayCount => C4::Context->preference("StaffSerialIssueDisplayCount"),
365
            NoZebra                     => C4::Context->preference('NoZebra'),
366
            EasyAnalyticalRecords       => C4::Context->preference('EasyAnalyticalRecords'),
365
            EasyAnalyticalRecords       => C4::Context->preference('EasyAnalyticalRecords'),
367
            LocalCoverImages            => C4::Context->preference('LocalCoverImages'),
366
            LocalCoverImages            => C4::Context->preference('LocalCoverImages'),
368
            OPACLocalCoverImages        => C4::Context->preference('OPACLocalCoverImages'),
367
            OPACLocalCoverImages        => C4::Context->preference('OPACLocalCoverImages'),
(-)a/C4/AuthoritiesMarc.pm (-320 / +207 lines)
Lines 109-391 sub SearchAuthorities { Link Here
109
    my ($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby,$skipmetadata) = @_;
109
    my ($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby,$skipmetadata) = @_;
110
    # warn Dumper($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby);
110
    # warn Dumper($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby);
111
    my $dbh=C4::Context->dbh;
111
    my $dbh=C4::Context->dbh;
112
    if (C4::Context->preference('NoZebra')) {
112
113
    
113
    my $query;
114
        #
114
    my $attr = '';
115
        # build the query
115
    # the marclist may contain "mainentry". In this case, search the tag_to_report, that depends on
116
        #
116
    # the authtypecode. Then, search on $a of this tag_to_report
117
        my $query;
117
    # also store main entry MARC tag, to extract it at end of search
118
    my $mainentrytag;
119
    ##first set the authtype search and may be multiple authorities
120
    if ($authtypecode) {
121
        my $n=0;
122
        my @authtypecode;
118
        my @auths=split / /,$authtypecode ;
123
        my @auths=split / /,$authtypecode ;
119
        foreach my  $auth (@auths){
124
        foreach my  $auth (@auths){
120
            $query .="AND auth_type= $auth ";
125
            $query .=" \@attr 1=authtype \@attr 5=100 ".$auth; ##No truncation on authtype
126
            push @authtypecode ,$auth;
127
            $n++;
121
        }
128
        }
122
        $query =~ s/^AND //;
129
        if ($n>1){
123
        my $dosearch;
130
            while ($n>1){$query= "\@or ".$query;$n--;}
124
        for(my $i = 0 ; $i <= $#{$value} ; $i++)
125
        {
126
            if (@$value[$i]){
127
                if (@$tags[$i] =~/mainentry|mainmainentry/) {
128
                    $query .= qq( AND @$tags[$i] );
129
                } else {
130
                    $query .=" AND ";
131
                }
132
                if (@$operator[$i] eq 'is') {
133
                    $query.=(@$tags[$i]?"=":""). '"'.@$value[$i].'"';
134
                }elsif (@$operator[$i] eq "="){
135
                    $query.=(@$tags[$i]?"=":""). '"'.@$value[$i].'"';
136
                }elsif (@$operator[$i] eq "start"){
137
                    $query.=(@$tags[$i]?"=":"").'"'.@$value[$i].'%"';
138
                } else {
139
                    $query.=(@$tags[$i]?"=":"").'"'.@$value[$i].'%"';
140
                }
141
                $dosearch=1;
142
            }#if value
143
        }
131
        }
144
        #
132
    }
145
        # do the query (if we had some search term
133
146
        #
134
    my $dosearch;
147
        if ($dosearch) {
135
    my $and=" \@and " ;
148
#             warn "QUERY : $query";
136
    my $q2;
149
            my $result = C4::Search::NZanalyse($query,'authorityserver');
137
    my $attr_cnt = 0;
150
#             warn "result : $result";
138
    for(my $i = 0 ; $i <= $#{$value} ; $i++)
151
            my %result;
139
    {
152
            foreach (split /;/,$result) {
140
        if (@$value[$i]){
153
                my ($authid,$title) = split /,/,$_;
141
            if ( @$tags[$i] eq "mainmainentry" ) {
154
                # hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
142
                $attr = " \@attr 1=Heading-Main ";
155
                # and we don't want to get only 1 result for each of them !!!
156
                # hint & speed improvement : we can order without reading the record
157
                # so order, and read records only for the requested page !
158
                $result{$title.$authid}=$authid;
159
            }
143
            }
160
            # sort the hash and return the same structure as GetRecords (Zebra querying)
144
            elsif ( @$tags[$i] eq "mainentry" ) {
161
            my @listresult = ();
145
                $attr = " \@attr 1=Heading ";
162
            my $numbers=0;
163
            if ($sortby eq 'HeadingDsc') { # sort by mainmainentry desc
164
                foreach my $key (sort {$b cmp $a} (keys %result)) {
165
                    push @listresult, $result{$key};
166
#                     warn "push..."$#finalresult;
167
                    $numbers++;
168
                }
169
            } else { # sort by mainmainentry ASC
170
                foreach my $key (sort (keys %result)) {
171
                    push @listresult, $result{$key};
172
#                     warn "push..."$#finalresult;
173
                    $numbers++;
174
                }
175
            }
146
            }
176
            # limit the $results_per_page to result size if it's more
147
            elsif ( @$tags[$i] eq "match" ) {
177
            $length = $numbers-$offset if $numbers < ($offset+$length);
148
                $attr = " \@attr 1=Match ";
178
            # for the requested page, replace authid by the complete record
179
            # speed improvement : avoid reading too much things
180
            my @finalresult;      
181
            for (my $counter=$offset;$counter<=$offset+$length-1;$counter++) {
182
#                 $finalresult[$counter] = GetAuthority($finalresult[$counter])->as_usmarc;
183
                my $separator=C4::Context->preference('authoritysep');
184
                my $authrecord =GetAuthority($listresult[$counter]);
185
                my $authid=$listresult[$counter]; 
186
                my $summary=BuildSummary($authrecord,$authid,$authtypecode);
187
                my $query_auth_tag = "SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?";
188
                my $sth = $dbh->prepare($query_auth_tag);
189
                $sth->execute($authtypecode);
190
                my $auth_tag_to_report = $sth->fetchrow;
191
                my %newline;
192
                $newline{used}=CountUsage($authid);
193
                $newline{summary} = $summary;
194
                $newline{authid} = $authid;
195
                $newline{even} = $counter % 2;
196
                push @finalresult, \%newline;
197
            }
149
            }
198
            return (\@finalresult, $numbers);
150
            elsif ( @$tags[$i] eq "match-heading" ) {
199
        } else {
151
                $attr = " \@attr 1=Match-heading ";
200
            return;
201
        }
202
    } else {
203
        my $query;
204
        my $attr = '';
205
            # the marclist may contain "mainentry". In this case, search the tag_to_report, that depends on
206
            # the authtypecode. Then, search on $a of this tag_to_report
207
            # also store main entry MARC tag, to extract it at end of search
208
        my $mainentrytag;
209
        ##first set the authtype search and may be multiple authorities
210
        if ($authtypecode) {
211
            my $n=0;
212
            my @authtypecode;
213
            my @auths=split / /,$authtypecode ;
214
            foreach my  $auth (@auths){
215
                $query .=" \@attr 1=authtype \@attr 5=100 ".$auth; ##No truncation on authtype
216
                    push @authtypecode ,$auth;
217
                $n++;
218
            }
152
            }
219
            if ($n>1){
153
            elsif ( @$tags[$i] eq "see-from" ) {
220
                while ($n>1){$query= "\@or ".$query;$n--;}
154
                $attr = " \@attr 1=Match-heading-see-from ";
221
            }
155
            }
222
        }
156
            elsif ( @$tags[$i] eq "thesaurus" ) {
223
        
157
                $attr = " \@attr 1=Subject-heading-thesaurus ";
224
        my $dosearch;
158
            }
225
        my $and=" \@and " ;
159
            else { # Assume any if no index was specified
226
        my $q2;
160
                $attr = " \@attr 1=Any ";
227
        my $attr_cnt = 0;
161
            }
228
        for(my $i = 0 ; $i <= $#{$value} ; $i++)
162
            if ( @$operator[$i] eq 'is' ) {
229
        {
163
                $attr .= " \@attr 4=1  \@attr 5=100 "
230
            if (@$value[$i]){
164
                  ; ##Phrase, No truncation,all of subfield field must match
231
                if ( @$tags[$i] eq "mainmainentry" ) {
165
            }
232
                    $attr = " \@attr 1=Heading-Main ";
166
            elsif ( @$operator[$i] eq "=" ) {
233
                }
167
                $attr .= " \@attr 4=107 ";    #Number Exact match
234
                elsif ( @$tags[$i] eq "mainentry" ) {
168
            }
235
                    $attr = " \@attr 1=Heading ";
169
            elsif ( @$operator[$i] eq "start" ) {
236
                }
170
                $attr .= " \@attr 3=2 \@attr 4=1 \@attr 5=1 "
237
                elsif ( @$tags[$i] eq "match" ) {
171
                  ;    #Firstinfield Phrase, Right truncated
238
                    $attr = " \@attr 1=Match ";
172
            }
239
                }
173
            elsif ( @$operator[$i] eq "exact" ) {
240
                elsif ( @$tags[$i] eq "match-heading" ) {
174
                $attr .= " \@attr 4=1  \@attr 5=100 \@attr 6=3 "
241
                    $attr = " \@attr 1=Match-heading ";
175
                  ; ##Phrase, No truncation,all of subfield field must match
242
                }
176
            }
243
                elsif ( @$tags[$i] eq "see-from" ) {
177
            else {
244
                    $attr = " \@attr 1=Match-heading-see-from ";
178
                $attr .= " \@attr 5=1 \@attr 4=6 "
245
                }
179
                  ;    ## Word list, right truncated, anywhere
246
                elsif ( @$tags[$i] eq "thesaurus" ) {
180
                if ($sortby eq 'Relevance') {
247
                    $attr = " \@attr 1=Subject-heading-thesaurus ";
181
                    $attr .= "\@attr 2=102 ";
248
                }
249
                else { # Assume any if no index was specified
250
                    $attr = " \@attr 1=Any ";
251
                }
252
                if ( @$operator[$i] eq 'is' ) {
253
                    $attr .= " \@attr 4=1  \@attr 5=100 "
254
                      ; ##Phrase, No truncation,all of subfield field must match
255
                }
256
                elsif ( @$operator[$i] eq "=" ) {
257
                    $attr .= " \@attr 4=107 ";    #Number Exact match
258
                }
259
                elsif ( @$operator[$i] eq "start" ) {
260
                    $attr .= " \@attr 3=2 \@attr 4=1 \@attr 5=1 "
261
                      ;    #Firstinfield Phrase, Right truncated
262
                }
263
                elsif ( @$operator[$i] eq "exact" ) {
264
                    $attr .= " \@attr 4=1  \@attr 5=100 \@attr 6=3 "
265
                      ; ##Phrase, No truncation,all of subfield field must match
266
                }
267
                else {
268
                    $attr .= " \@attr 5=1 \@attr 4=6 "
269
                      ;    ## Word list, right truncated, anywhere
270
                      if ($sortby eq 'Relevance') {
271
                          $attr .= "\@attr 2=102 ";
272
                      }
273
                }
182
                }
274
                @$value[$i] =~ s/"/\\"/g; # Escape the double-quotes in the search value
183
            }
275
                $attr =$attr."\"".@$value[$i]."\"";
184
            @$value[$i] =~ s/"/\\"/g; # Escape the double-quotes in the search value
276
                $q2 .=$attr;
185
            $attr =$attr."\"".@$value[$i]."\"";
277
                $dosearch=1;
186
            $q2 .=$attr;
278
                ++$attr_cnt;
187
            $dosearch=1;
279
            }#if value
188
            ++$attr_cnt;
280
        }
189
        }#if value
281
        ##Add how many queries generated
190
    }
282
        if (defined $query && $query=~/\S+/){
191
283
          $query= $and x $attr_cnt . $query . (defined $q2 ? $q2 : '');
192
    ##Add how many queries generated
284
        } else {
193
    if (defined $query && $query=~/\S+/){
285
          $query= $q2;
194
      $query= $and x $attr_cnt . $query . (defined $q2 ? $q2 : '');
286
        }
195
    } else {
287
        ## Adding order
196
      $query= $q2;
288
        #$query=' @or  @attr 7=2 @attr 1=Heading 0 @or  @attr 7=1 @attr 1=Heading 1'.$query if ($sortby eq "HeadingDsc");
197
    }
289
        my $orderstring;
198
    ## Adding order
290
        if ($sortby eq 'HeadingAsc') {
199
    #$query=' @or  @attr 7=2 @attr 1=Heading 0 @or  @attr 7=1 @attr 1=Heading 1'.$query if ($sortby eq "HeadingDsc");
291
            $orderstring = '@attr 7=1 @attr 1=Heading 0';
200
    my $orderstring;
292
        } elsif ($sortby eq 'HeadingDsc') {
201
    if ($sortby eq 'HeadingAsc') {
293
            $orderstring = '@attr 7=2 @attr 1=Heading 0';
202
        $orderstring = '@attr 7=1 @attr 1=Heading 0';
294
        } elsif ($sortby eq 'AuthidAsc') {
203
    } elsif ($sortby eq 'HeadingDsc') {
295
            $orderstring = '@attr 7=1 @attr 4=109 @attr 1=Local-Number 0';
204
        $orderstring = '@attr 7=2 @attr 1=Heading 0';
296
        } elsif ($sortby eq 'AuthidDsc') {
205
    } elsif ($sortby eq 'AuthidAsc') {
297
            $orderstring = '@attr 7=2 @attr 4=109 @attr 1=Local-Number 0';
206
        $orderstring = '@attr 7=1 @attr 4=109 @attr 1=Local-Number 0';
298
        }
207
    } elsif ($sortby eq 'AuthidDsc') {
299
        $query=($query?$query:"\@attr 1=_ALLRECORDS \@attr 2=103 ''");
208
        $orderstring = '@attr 7=2 @attr 4=109 @attr 1=Local-Number 0';
300
        $query="\@or $orderstring $query" if $orderstring;
209
    }
301
210
    $query=($query?$query:"\@attr 1=_ALLRECORDS \@attr 2=103 ''");
302
        $offset=0 unless $offset;
211
    $query="\@or $orderstring $query" if $orderstring;
303
        my $counter = $offset;
212
304
        $length=10 unless $length;
213
    $offset=0 unless $offset;
305
        my @oAuth;
214
    my $counter = $offset;
306
        my $i;
215
    $length=10 unless $length;
307
        $oAuth[0]=C4::Context->Zconn("authorityserver" , 1);
216
    my @oAuth;
308
        my $Anewq= new ZOOM::Query::PQF($query,$oAuth[0]);
217
    my $i;
309
        my $oAResult;
218
    $oAuth[0]=C4::Context->Zconn("authorityserver" , 1);
310
        $oAResult= $oAuth[0]->search($Anewq) ; 
219
    my $Anewq= new ZOOM::Query::PQF($query,$oAuth[0]);
311
        while (($i = ZOOM::event(\@oAuth)) != 0) {
220
    my $oAResult;
312
            my $ev = $oAuth[$i-1]->last_event();
221
    $oAResult= $oAuth[0]->search($Anewq);
313
            last if $ev == ZOOM::Event::ZEND;
222
    while (($i = ZOOM::event(\@oAuth)) != 0) {
314
        }
223
        my $ev = $oAuth[$i-1]->last_event();
315
        my($error, $errmsg, $addinfo, $diagset) = $oAuth[0]->error_x();
224
        last if $ev == ZOOM::Event::ZEND;
316
        if ($error) {
225
    }
317
            warn  "oAuth error: $errmsg ($error) $addinfo $diagset\n";
226
    my($error, $errmsg, $addinfo, $diagset) = $oAuth[0]->error_x();
318
            goto NOLUCK;
227
    if ($error) {
319
        }
228
        warn  "oAuth error: $errmsg ($error) $addinfo $diagset\n";
320
        
229
        goto NOLUCK;
321
        my $nbresults;
230
    }
322
        $nbresults=$oAResult->size();
231
323
        my $nremains=$nbresults;    
232
    my $nbresults;
324
        my @result = ();
233
    $nbresults=$oAResult->size();
325
        my @finalresult = ();
234
    my $nremains=$nbresults;
326
        
235
    my @result = ();
327
        if ($nbresults>0){
236
    my @finalresult = ();
328
        
237
329
        ##Find authid and linkid fields
238
    if ($nbresults>0){
330
        ##we may be searching multiple authoritytypes.
239
331
        ## FIXME this assumes that all authid and linkid fields are the same for all authority types
240
    ##Find authid and linkid fields
332
        # my ($authidfield,$authidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.authid",$authtypecode[0]);
241
    ##we may be searching multiple authoritytypes.
333
        # my ($linkidfield,$linkidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.linkid",$authtypecode[0]);
242
    ## FIXME this assumes that all authid and linkid fields are the same for all authority types
334
            while (($counter < $nbresults) && ($counter < ($offset + $length))) {
243
    # my ($authidfield,$authidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.authid",$authtypecode[0]);
335
            
244
    # my ($linkidfield,$linkidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.linkid",$authtypecode[0]);
336
            ##Here we have to extract MARC record and $authid from ZEBRA AUTHORITIES
245
        while (($counter < $nbresults) && ($counter < ($offset + $length))) {
337
            my $rec=$oAResult->record($counter);
246
338
            my $marcdata=$rec->raw();
247
        ##Here we have to extract MARC record and $authid from ZEBRA AUTHORITIES
339
            my $authrecord;
248
        my $rec=$oAResult->record($counter);
340
            my $separator=C4::Context->preference('authoritysep');
249
        my $marcdata=$rec->raw();
341
            $authrecord = MARC::File::USMARC::decode($marcdata);
250
        my $authrecord;
342
            my $authid=$authrecord->field('001')->data(); 
251
        my $separator=C4::Context->preference('authoritysep');
343
            my %newline;
252
        $authrecord = MARC::File::USMARC::decode($marcdata);
344
            $newline{authid} = $authid;
253
        my $authid=$authrecord->field('001')->data();
345
            if ( !$skipmetadata ) {
254
        my %newline;
346
                my $summary =
255
        $newline{authid} = $authid;
347
                  BuildSummary( $authrecord, $authid, $authtypecode );
256
        if ( !$skipmetadata ) {
348
                my $query_auth_tag =
257
            my $summary =
258
              BuildSummary( $authrecord, $authid, $authtypecode );
259
            my $query_auth_tag =
349
"SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?";
260
"SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?";
350
                my $sth = $dbh->prepare($query_auth_tag);
261
            my $sth = $dbh->prepare($query_auth_tag);
351
                $sth->execute($authtypecode);
262
            $sth->execute($authtypecode);
352
                my $auth_tag_to_report = $sth->fetchrow;
263
            my $auth_tag_to_report = $sth->fetchrow;
353
                my $reported_tag;
264
            my $reported_tag;
354
                my $mainentry = $authrecord->field($auth_tag_to_report);
265
            my $mainentry = $authrecord->field($auth_tag_to_report);
355
                if ($mainentry) {
266
            if ($mainentry) {
356
267
357
                    foreach ( $mainentry->subfields() ) {
268
                foreach ( $mainentry->subfields() ) {
358
                        $reported_tag .= '$' . $_->[0] . $_->[1];
269
                    $reported_tag .= '$' . $_->[0] . $_->[1];
359
                    }
360
                }
361
                my $thisauthtype = GetAuthType(GetAuthTypeCode($authid));
362
                unless (defined $thisauthtype) {
363
                    $thisauthtype = GetAuthType($authtypecode) if $authtypecode;
364
                }
270
                }
365
                $newline{authtype}     = defined($thisauthtype) ?
366
                                            $thisauthtype->{'authtypetext'} : '';
367
                $newline{summary}      = $summary;
368
                $newline{even}         = $counter % 2;
369
                $newline{reported_tag} = $reported_tag;
370
            }
271
            }
371
            $counter++;
272
            my $thisauthtype = GetAuthType(GetAuthTypeCode($authid));
372
            push @finalresult, \%newline;
273
            unless (defined $thisauthtype) {
373
            }## while counter
274
                $thisauthtype = GetAuthType($authtypecode) if $authtypecode;
374
            ###
375
            if (! $skipmetadata) {
376
                for (my $z=0; $z<@finalresult; $z++){
377
                    my  $count=CountUsage($finalresult[$z]{authid});
378
                    $finalresult[$z]{used}=$count;
379
                }# all $z's
380
            }
275
            }
276
            $newline{authtype}     = defined($thisauthtype) ?
277
                                        $thisauthtype->{'authtypetext'} : '';
278
            $newline{summary}      = $summary;
279
            $newline{even}         = $counter % 2;
280
            $newline{reported_tag} = $reported_tag;
281
        }
282
        $counter++;
283
        push @finalresult, \%newline;
284
        }## while counter
285
        ###
286
        if (! $skipmetadata) {
287
            for (my $z=0; $z<@finalresult; $z++){
288
                my  $count=CountUsage($finalresult[$z]{authid});
289
                $finalresult[$z]{used}=$count;
290
            }# all $z's
291
        }
381
292
382
        }## if nbresult
293
    }## if nbresult
383
        NOLUCK:
294
    NOLUCK:
384
        $oAResult->destroy();
295
    $oAResult->destroy();
385
        # $oAuth[0]->destroy();
296
    # $oAuth[0]->destroy();
386
        
297
387
        return (\@finalresult, $nbresults);
298
    return (\@finalresult, $nbresults);
388
    }
389
}
299
}
390
300
391
=head2 CountUsage 
301
=head2 CountUsage 
Lines 398-420 counts Usage of Authid in bibliorecords. Link Here
398
308
399
sub CountUsage {
309
sub CountUsage {
400
    my ($authid) = @_;
310
    my ($authid) = @_;
401
    if (C4::Context->preference('NoZebra')) {
402
        # Read the index Koha-Auth-Number for this authid and count the lines
403
        my $result = C4::Search::NZanalyse("an=$authid");
404
        my @tab = split /;/,$result;
405
        return scalar @tab;
406
    } else {
407
        ### ZOOM search here
408
        my $query;
409
        $query= "an=".$authid;
410
  		my ($err,$res,$result) = C4::Search::SimpleSearch($query,0,10);
411
        if ($err) {
412
            warn "Error: $err from search $query";
413
            $result = 0;
414
        }
415
311
416
        return $result;
312
    my $query;
313
    $query= "an=".$authid;
314
    my ($err,$res,$result) = C4::Search::SimpleSearch($query,0,10);
315
    if ($err) {
316
        warn "Error: $err from search $query";
317
        $result = 0;
417
    }
318
    }
319
320
    return $result;
418
}
321
}
419
322
420
=head2 CountUsageChildren 
323
=head2 CountUsageChildren 
Lines 734-740 sub AddAuthority { Link Here
734
  }
637
  }
735
638
736
  my $auth_exists=0;
639
  my $auth_exists=0;
737
  my $oldRecord;
738
  if (!$authid) {
640
  if (!$authid) {
739
    my $sth=$dbh->prepare("select max(authid) from auth_header");
641
    my $sth=$dbh->prepare("select max(authid) from auth_header");
740
    $sth->execute;
642
    $sth->execute;
Lines 750-756 sub AddAuthority { Link Here
750
#     warn "auth_exists = $auth_exists";
652
#     warn "auth_exists = $auth_exists";
751
  }
653
  }
752
  if ($auth_exists>0){
654
  if ($auth_exists>0){
753
      $oldRecord=GetAuthority($authid);
754
      $record->add_fields('001',$authid) unless ($record->field('001'));
655
      $record->add_fields('001',$authid) unless ($record->field('001'));
755
#       warn "\n\n\n enregistrement".$record->as_formatted;
656
#       warn "\n\n\n enregistrement".$record->as_formatted;
756
      my $sth=$dbh->prepare("update auth_header set authtypecode=?,marc=?,marcxml=? where authid=?");
657
      my $sth=$dbh->prepare("update auth_header set authtypecode=?,marc=?,marcxml=? where authid=?");
Lines 763-769 sub AddAuthority { Link Here
763
    $sth->finish;
664
    $sth->finish;
764
    logaction( "AUTHORITIES", "ADD", $authid, "authority" ) if C4::Context->preference("AuthoritiesLog");
665
    logaction( "AUTHORITIES", "ADD", $authid, "authority" ) if C4::Context->preference("AuthoritiesLog");
765
  }
666
  }
766
  ModZebra($authid,'specialUpdate',"authorityserver",$oldRecord,$record);
667
  ModZebra( $authid,"specialUpdate","authorityserver" );
767
  return ($authid);
668
  return ($authid);
768
}
669
}
769
670
Lines 781-787 sub DelAuthority { Link Here
781
    my $dbh=C4::Context->dbh;
682
    my $dbh=C4::Context->dbh;
782
683
783
    logaction( "AUTHORITIES", "DELETE", $authid, "authority" ) if C4::Context->preference("AuthoritiesLog");
684
    logaction( "AUTHORITIES", "DELETE", $authid, "authority" ) if C4::Context->preference("AuthoritiesLog");
784
    ModZebra($authid,"recordDelete","authorityserver",GetAuthority($authid),undef);
685
    ModZebra( $authid,"recordDelete","authorityserver" );
785
    my $sth = $dbh->prepare("DELETE FROM auth_header WHERE authid=?");
686
    my $sth = $dbh->prepare("DELETE FROM auth_header WHERE authid=?");
786
    $sth->execute($authid);
687
    $sth->execute($authid);
787
}
688
}
Lines 1474-1519 sub merge { Link Here
1474
    my @reccache;
1375
    my @reccache;
1475
    # search all biblio tags using this authority.
1376
    # search all biblio tags using this authority.
1476
    #Getting marcbiblios impacted by the change.
1377
    #Getting marcbiblios impacted by the change.
1477
    if (C4::Context->preference('NoZebra')) {
1378
1478
        #nozebra way    
1379
    #zebra connection
1479
        my $dbh=C4::Context->dbh;
1380
    my $oConnection=C4::Context->Zconn("biblioserver",0);
1480
        my $rq=$dbh->prepare(qq(SELECT biblionumbers from nozebra where indexname="an" and server="biblioserver" and value="$mergefrom" ));
1381
    # We used to use XML syntax here, but that no longer works.
1481
        $rq->execute;
1382
    # Thankfully, we don't need it.
1482
        while (my $biblionumbers=$rq->fetchrow){
1383
    my $query;
1483
            my @biblionumbers=split /;/,$biblionumbers;
1384
    $query= "an=".$mergefrom;
1484
            foreach (@biblionumbers) {
1385
    my $oResult = $oConnection->search(new ZOOM::Query::CCL2RPN( $query, $oConnection ));
1485
                if ($_=~/(\d+),.*/) {
1386
    my $count = 0;
1486
                    my $marc=GetMarcBiblio($1);
1387
    if  ($oResult) {
1487
                    push @reccache,$marc;
1388
        $count=$oResult->size();
1488
                }
1489
            }
1490
        }
1491
    } else {
1492
        #zebra connection  
1493
        my $oConnection=C4::Context->Zconn("biblioserver",0);
1494
        # We used to use XML syntax here, but that no longer works.
1495
        # Thankfully, we don't need it.
1496
        my $query;
1497
        $query= "an=".$mergefrom;
1498
        my $oResult = $oConnection->search(new ZOOM::Query::CCL2RPN( $query, $oConnection ));
1499
        my $count = 0;
1500
        if  ($oResult) {
1501
            $count=$oResult->size();
1502
        }
1503
        my $z=0;
1504
        while ( $z<$count ) {
1505
            my $rec;
1506
            $rec=$oResult->record($z);
1507
            my $marcdata = $rec->raw();
1508
            my $marcrecordzebra= MARC::Record->new_from_usmarc($marcdata);
1509
            my ( $biblionumbertagfield, $biblionumbertagsubfield ) = &GetMarcFromKohaField( "biblio.biblionumber", '' );
1510
            my $i = ($biblionumbertagfield < 10) ? $marcrecordzebra->field($biblionumbertagfield)->data : $marcrecordzebra->subfield($biblionumbertagfield, $biblionumbertagsubfield);
1511
            my $marcrecorddb=GetMarcBiblio($i);
1512
            push @reccache, $marcrecorddb;
1513
            $z++;
1514
        }
1515
        $oResult->destroy();
1516
    }
1389
    }
1390
    my $z=0;
1391
    while ( $z<$count ) {
1392
        my $rec;
1393
        $rec=$oResult->record($z);
1394
        my $marcdata = $rec->raw();
1395
        my $marcrecordzebra= MARC::Record->new_from_usmarc($marcdata);
1396
        my ( $biblionumbertagfield, $biblionumbertagsubfield ) = &GetMarcFromKohaField( "biblio.biblionumber", '' );
1397
        my $i = ($biblionumbertagfield < 10) ? $marcrecordzebra->field($biblionumbertagfield)->data : $marcrecordzebra->subfield($biblionumbertagfield, $biblionumbertagsubfield);
1398
        my $marcrecorddb=GetMarcBiblio($i);
1399
        push @reccache, $marcrecorddb;
1400
        $z++;
1401
    }
1402
    $oResult->destroy();
1403
1517
    #warn scalar(@reccache)." biblios to update";
1404
    #warn scalar(@reccache)." biblios to update";
1518
    # Get All candidate Tags for the change 
1405
    # Get All candidate Tags for the change 
1519
    # (This will reduce the search scope in marc records).
1406
    # (This will reduce the search scope in marc records).
(-)a/C4/Biblio.pm (-361 / +18 lines)
Lines 136-142 BEGIN { Link Here
136
      &TransformHtmlToMarc2
136
      &TransformHtmlToMarc2
137
      &TransformHtmlToMarc
137
      &TransformHtmlToMarc
138
      &TransformHtmlToXml
138
      &TransformHtmlToXml
139
      &GetNoZebraIndexes
140
      prepare_host_field
139
      prepare_host_field
141
    );
140
    );
142
}
141
}
Lines 444-460 sub DelBiblio { Link Here
444
443
445
    # Delete in Zebra. Be careful NOT to move this line after _koha_delete_biblio
444
    # Delete in Zebra. Be careful NOT to move this line after _koha_delete_biblio
446
    # for at least 2 reasons :
445
    # for at least 2 reasons :
447
    # - we need to read the biblio if NoZebra is set (to remove it from the indexes
448
    # - if something goes wrong, the biblio may be deleted from Koha but not from zebra
446
    # - if something goes wrong, the biblio may be deleted from Koha but not from zebra
449
    #   and we would have no way to remove it (except manually in zebra, but I bet it would be very hard to handle the problem)
447
    #   and we would have no way to remove it (except manually in zebra, but I bet it would be very hard to handle the problem)
450
    my $oldRecord;
448
    ModZebra( $biblionumber, "recordDelete", "biblioserver" );
451
    if ( C4::Context->preference("NoZebra") ) {
452
453
        # only NoZebra indexing needs to have
454
        # the previous version of the record
455
        $oldRecord = GetMarcBiblio($biblionumber);
456
    }
457
    ModZebra( $biblionumber, "recordDelete", "biblioserver", $oldRecord, undef );
458
449
459
    # delete biblioitems and items from Koha tables and save in deletedbiblioitems,deleteditems
450
    # delete biblioitems and items from Koha tables and save in deletedbiblioitems,deleteditems
460
    $sth = $dbh->prepare("SELECT biblioitemnumber FROM biblioitems WHERE biblionumber=?");
451
    $sth = $dbh->prepare("SELECT biblioitemnumber FROM biblioitems WHERE biblionumber=?");
Lines 2769-2775 sub TransformMarcToKohaOneField { Link Here
2769
2760
2770
=head2 ModZebra
2761
=head2 ModZebra
2771
2762
2772
  ModZebra( $biblionumber, $op, $server, $oldRecord, $newRecord );
2763
  ModZebra( $biblionumber, $op, $server );
2773
2764
2774
$biblionumber is the biblionumber we want to index
2765
$biblionumber is the biblionumber we want to index
2775
2766
Lines 2777-2875 $op is specialUpdate or delete, and is used to know what we want to do Link Here
2777
2768
2778
$server is the server that we want to update
2769
$server is the server that we want to update
2779
2770
2780
$oldRecord is the MARC::Record containing the previous version of the record.  This is used only when 
2781
NoZebra=1, as NoZebra indexing needs to know the previous version of a record in order to
2782
do an update.
2783
2784
$newRecord is the MARC::Record containing the new record. It is usefull only when NoZebra=1, and is used to know what to add to the nozebra database. (the record in mySQL being, if it exist, the previous record, the one just before the modif. We need both : the previous and the new one.
2785
2786
=cut
2771
=cut
2787
2772
2788
sub ModZebra {
2773
sub ModZebra {
2789
###Accepts a $server variable thus we can use it for biblios authorities or other zebra dbs
2774
###Accepts a $server variable thus we can use it for biblios authorities or other zebra dbs
2790
    my ( $biblionumber, $op, $server, $oldRecord, $newRecord ) = @_;
2775
    my ( $biblionumber, $op, $server ) = @_;
2791
    my $dbh = C4::Context->dbh;
2776
    my $dbh = C4::Context->dbh;
2792
2777
2793
    # true ModZebra commented until indexdata fixes zebraDB crashes (it seems they occur on multiple updates
2778
    # true ModZebra commented until indexdata fixes zebraDB crashes (it seems they occur on multiple updates
2794
    # at the same time
2779
    # at the same time
2795
    # replaced by a zebraqueue table, that is filled with ModZebra to run.
2780
    # replaced by a zebraqueue table, that is filled with ModZebra to run.
2796
    # the table is emptied by misc/cronjobs/zebraqueue_start.pl script
2781
    # the table is emptied by rebuild_zebra.pl script (using the -z switch)
2797
2782
2798
    if ( C4::Context->preference("NoZebra") ) {
2783
    my $check_sql = "SELECT COUNT(*) FROM zebraqueue
2799
2784
                     WHERE server = ?
2800
        # lock the nozebra table : we will read index lines, update them in Perl process
2785
                     AND   biblio_auth_number = ?
2801
        # and write everything in 1 transaction.
2786
                     AND   operation = ?
2802
        # lock the table to avoid someone else overwriting what we are doing
2787
                     AND   done = 0";
2803
        $dbh->do('LOCK TABLES nozebra WRITE,biblio WRITE,biblioitems WRITE, systempreferences WRITE, auth_types WRITE, auth_header WRITE, auth_subfield_structure READ');
2788
    my $check_sth = $dbh->prepare_cached($check_sql);
2804
        my %result;    # the result hash that will be built by deletion / add, and written on mySQL at the end, to improve speed
2789
    $check_sth->execute( $server, $biblionumber, $op );
2805
        if ( $op eq 'specialUpdate' ) {
2790
    my ($count) = $check_sth->fetchrow_array;
2806
2791
    $check_sth->finish();
2807
            # OK, we have to add or update the record
2792
    if ( $count == 0 ) {
2808
            # 1st delete (virtually, in indexes), if record actually exists
2793
        my $sth = $dbh->prepare("INSERT INTO zebraqueue  (biblio_auth_number,server,operation) VALUES(?,?,?)");
2809
            if ($oldRecord) {
2794
        $sth->execute( $biblionumber, $server, $op );
2810
                %result = _DelBiblioNoZebra( $biblionumber, $oldRecord, $server );
2795
        $sth->finish;
2811
            }
2812
2813
            # ... add the record
2814
            %result = _AddBiblioNoZebra( $biblionumber, $newRecord, $server, %result );
2815
        } else {
2816
2817
            # it's a deletion, delete the record...
2818
            # warn "DELETE the record $biblionumber on $server".$record->as_formatted;
2819
            %result = _DelBiblioNoZebra( $biblionumber, $oldRecord, $server );
2820
        }
2821
2822
        # ok, now update the database...
2823
        my $sth = $dbh->prepare("UPDATE nozebra SET biblionumbers=? WHERE server=? AND indexname=? AND value=?");
2824
        foreach my $key ( keys %result ) {
2825
            foreach my $index ( keys %{ $result{$key} } ) {
2826
                $sth->execute( $result{$key}->{$index}, $server, $key, $index );
2827
            }
2828
        }
2829
        $dbh->do('UNLOCK TABLES');
2830
    } else {
2831
2832
        #
2833
        # we use zebra, just fill zebraqueue table
2834
        #
2835
        my $check_sql = "SELECT COUNT(*) FROM zebraqueue 
2836
                         WHERE server = ?
2837
                         AND   biblio_auth_number = ?
2838
                         AND   operation = ?
2839
                         AND   done = 0";
2840
        my $check_sth = $dbh->prepare_cached($check_sql);
2841
        $check_sth->execute( $server, $biblionumber, $op );
2842
        my ($count) = $check_sth->fetchrow_array;
2843
        $check_sth->finish();
2844
        if ( $count == 0 ) {
2845
            my $sth = $dbh->prepare("INSERT INTO zebraqueue  (biblio_auth_number,server,operation) VALUES(?,?,?)");
2846
            $sth->execute( $biblionumber, $server, $op );
2847
            $sth->finish;
2848
        }
2849
    }
2796
    }
2850
}
2797
}
2851
2798
2852
=head2 GetNoZebraIndexes
2853
2854
  %indexes = GetNoZebraIndexes;
2855
2856
return the data from NoZebraIndexes syspref.
2857
2858
=cut
2859
2860
sub GetNoZebraIndexes {
2861
    my $no_zebra_indexes = C4::Context->preference('NoZebraIndexes');
2862
    my %indexes;
2863
  INDEX: foreach my $line ( split /['"],[\n\r]*/, $no_zebra_indexes ) {
2864
        $line =~ /(.*)=>(.*)/;
2865
        my $index  = $1;    # initial ' or " is removed afterwards
2866
        my $fields = $2;
2867
        $index  =~ s/'|"|\s//g;
2868
        $fields =~ s/'|"|\s//g;
2869
        $indexes{$index} = $fields;
2870
    }
2871
    return %indexes;
2872
}
2873
2799
2874
=head2 EmbedItemsInMarcBiblio
2800
=head2 EmbedItemsInMarcBiblio
2875
2801
Lines 2908-3175 sub EmbedItemsInMarcBiblio { Link Here
2908
2834
2909
=head1 INTERNAL FUNCTIONS
2835
=head1 INTERNAL FUNCTIONS
2910
2836
2911
=head2 _DelBiblioNoZebra($biblionumber,$record,$server);
2912
2913
function to delete a biblio in NoZebra indexes
2914
This function does NOT delete anything in database : it reads all the indexes entries
2915
that have to be deleted & delete them in the hash
2916
2917
The SQL part is done either :
2918
 - after the Add if we are modifying a biblio (delete + add again)
2919
 - immediatly after this sub if we are doing a true deletion.
2920
2921
$server can be 'biblioserver' or 'authorityserver' : it indexes biblios or authorities (in the same table, $server being part of the table itself
2922
2923
=cut
2924
2925
sub _DelBiblioNoZebra {
2926
    my ( $biblionumber, $record, $server ) = @_;
2927
2928
    # Get the indexes
2929
    my $dbh = C4::Context->dbh;
2930
2931
    # Get the indexes
2932
    my %index;
2933
    my $title;
2934
    if ( $server eq 'biblioserver' ) {
2935
        %index = GetNoZebraIndexes;
2936
2937
        # get title of the record (to store the 10 first letters with the index)
2938
        my ( $titletag, $titlesubfield ) = GetMarcFromKohaField( 'biblio.title', '' );    # FIXME: should be GetFrameworkCode($biblionumber) ??
2939
        $title = lc( $record->subfield( $titletag, $titlesubfield ) );
2940
    } else {
2941
2942
        # for authorities, the "title" is the $a mainentry
2943
        my ( $auth_type_tag, $auth_type_sf ) = C4::AuthoritiesMarc::get_auth_type_location();
2944
        my $authref = C4::AuthoritiesMarc::GetAuthType( $record->subfield( $auth_type_tag, $auth_type_sf ) );
2945
        warn "ERROR : authtype undefined for " . $record->as_formatted unless $authref;
2946
        $title = $record->subfield( $authref->{auth_tag_to_report}, 'a' );
2947
        $index{'mainmainentry'} = $authref->{'auth_tag_to_report'} . 'a';
2948
        $index{'mainentry'}     = $authref->{'auth_tag_to_report'} . '*';
2949
        $index{'auth_type'}     = "${auth_type_tag}${auth_type_sf}";
2950
    }
2951
2952
    my %result;
2953
2954
    # remove blancks comma (that could cause problem when decoding the string for CQL retrieval) and regexp specific values
2955
    $title =~ s/ |,|;|\[|\]|\(|\)|\*|-|'|=//g;
2956
2957
    # limit to 10 char, should be enough, and limit the DB size
2958
    $title = substr( $title, 0, 10 );
2959
2960
    #parse each field
2961
    my $sth2 = $dbh->prepare('SELECT biblionumbers FROM nozebra WHERE server=? AND indexname=? AND value=?');
2962
    foreach my $field ( $record->fields() ) {
2963
2964
        #parse each subfield
2965
        next if $field->tag < 10;
2966
        foreach my $subfield ( $field->subfields() ) {
2967
            my $tag          = $field->tag();
2968
            my $subfieldcode = $subfield->[0];
2969
            my $indexed      = 0;
2970
2971
            # check each index to see if the subfield is stored somewhere
2972
            # otherwise, store it in __RAW__ index
2973
            foreach my $key ( keys %index ) {
2974
2975
                #                 warn "examining $key index : ".$index{$key}." for $tag $subfieldcode";
2976
                if ( $index{$key} =~ /$tag\*/ or $index{$key} =~ /$tag$subfieldcode/ ) {
2977
                    $indexed = 1;
2978
                    my $line = lc $subfield->[1];
2979
2980
                    # remove meaningless value in the field...
2981
                    $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:/ /g;
2982
2983
                    # ... and split in words
2984
                    foreach ( split / /, $line ) {
2985
                        next unless $_;    # skip  empty values (multiple spaces)
2986
                                           # if the entry is already here, do nothing, the biblionumber has already be removed
2987
                        unless ( defined( $result{$key}->{$_} ) && ( $result{$key}->{$_} =~ /$biblionumber,$title\-(\d);/ ) ) {
2988
2989
                            # get the index value if it exist in the nozebra table and remove the entry, otherwise, do nothing
2990
                            $sth2->execute( $server, $key, $_ );
2991
                            my $existing_biblionumbers = $sth2->fetchrow;
2992
2993
                            # it exists
2994
                            if ($existing_biblionumbers) {
2995
2996
                                #                                 warn " existing for $key $_: $existing_biblionumbers";
2997
                                $result{$key}->{$_} = $existing_biblionumbers;
2998
                                $result{$key}->{$_} =~ s/$biblionumber,$title\-(\d);//;
2999
                            }
3000
                        }
3001
                    }
3002
                }
3003
            }
3004
3005
            # the subfield is not indexed, store it in __RAW__ index anyway
3006
            unless ($indexed) {
3007
                my $line = lc $subfield->[1];
3008
                $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:/ /g;
3009
3010
                # ... and split in words
3011
                foreach ( split / /, $line ) {
3012
                    next unless $_;    # skip  empty values (multiple spaces)
3013
                                       # if the entry is already here, do nothing, the biblionumber has already be removed
3014
                    unless ( $result{'__RAW__'}->{$_} =~ /$biblionumber,$title\-(\d);/ ) {
3015
3016
                        # get the index value if it exist in the nozebra table and remove the entry, otherwise, do nothing
3017
                        $sth2->execute( $server, '__RAW__', $_ );
3018
                        my $existing_biblionumbers = $sth2->fetchrow;
3019
3020
                        # it exists
3021
                        if ($existing_biblionumbers) {
3022
                            $result{'__RAW__'}->{$_} = $existing_biblionumbers;
3023
                            $result{'__RAW__'}->{$_} =~ s/$biblionumber,$title\-(\d);//;
3024
                        }
3025
                    }
3026
                }
3027
            }
3028
        }
3029
    }
3030
    return %result;
3031
}
3032
3033
=head2 _AddBiblioNoZebra
3034
3035
  _AddBiblioNoZebra($biblionumber, $record, $server, %result);
3036
3037
function to add a biblio in NoZebra indexes
3038
3039
=cut
3040
3041
sub _AddBiblioNoZebra {
3042
    my ( $biblionumber, $record, $server, %result ) = @_;
3043
    my $dbh = C4::Context->dbh;
3044
3045
    # Get the indexes
3046
    my %index;
3047
    my $title;
3048
    if ( $server eq 'biblioserver' ) {
3049
        %index = GetNoZebraIndexes;
3050
3051
        # get title of the record (to store the 10 first letters with the index)
3052
        my ( $titletag, $titlesubfield ) = GetMarcFromKohaField( 'biblio.title', '' );    # FIXME: should be GetFrameworkCode($biblionumber) ??
3053
        $title = lc( $record->subfield( $titletag, $titlesubfield ) );
3054
    } else {
3055
3056
        # warn "server : $server";
3057
        # for authorities, the "title" is the $a mainentry
3058
        my ( $auth_type_tag, $auth_type_sf ) = C4::AuthoritiesMarc::get_auth_type_location();
3059
        my $authref = C4::AuthoritiesMarc::GetAuthType( $record->subfield( $auth_type_tag, $auth_type_sf ) );
3060
        warn "ERROR : authtype undefined for " . $record->as_formatted unless $authref;
3061
        $title = $record->subfield( $authref->{auth_tag_to_report}, 'a' );
3062
        $index{'mainmainentry'} = $authref->{auth_tag_to_report} . 'a';
3063
        $index{'mainentry'}     = $authref->{auth_tag_to_report} . '*';
3064
        $index{'auth_type'}     = "${auth_type_tag}${auth_type_sf}";
3065
    }
3066
3067
    # remove blancks comma (that could cause problem when decoding the string for CQL retrieval) and regexp specific values
3068
    $title =~ s/ |\.|,|;|\[|\]|\(|\)|\*|-|'|:|=|\r|\n//g;
3069
3070
    # limit to 10 char, should be enough, and limit the DB size
3071
    $title = substr( $title, 0, 10 );
3072
3073
    #parse each field
3074
    my $sth2 = $dbh->prepare('SELECT biblionumbers FROM nozebra WHERE server=? AND indexname=? AND value=?');
3075
    foreach my $field ( $record->fields() ) {
3076
3077
        #parse each subfield
3078
        ###FIXME: impossible to index a 001-009 value with NoZebra
3079
        next if $field->tag < 10;
3080
        foreach my $subfield ( $field->subfields() ) {
3081
            my $tag          = $field->tag();
3082
            my $subfieldcode = $subfield->[0];
3083
            my $indexed      = 0;
3084
3085
            #             warn "INDEXING :".$subfield->[1];
3086
            # check each index to see if the subfield is stored somewhere
3087
            # otherwise, store it in __RAW__ index
3088
            foreach my $key ( keys %index ) {
3089
3090
                #                 warn "examining $key index : ".$index{$key}." for $tag $subfieldcode";
3091
                if ( $index{$key} =~ /$tag\*/ or $index{$key} =~ /$tag$subfieldcode/ ) {
3092
                    $indexed = 1;
3093
                    my $line = lc $subfield->[1];
3094
3095
                    # remove meaningless value in the field...
3096
                    $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:|\r|\n/ /g;
3097
3098
                    # ... and split in words
3099
                    foreach ( split / /, $line ) {
3100
                        next unless $_;    # skip  empty values (multiple spaces)
3101
                                           # if the entry is already here, improve weight
3102
3103
                        #                         warn "managing $_";
3104
                        if ( exists $result{$key}->{$_} && $result{$key}->{"$_"} =~ /$biblionumber,\Q$title\E\-(\d+);/ ) {
3105
                            my $weight = $1 + 1;
3106
                            $result{$key}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//g;
3107
                            $result{$key}->{"$_"} .= "$biblionumber,$title-$weight;";
3108
                        } else {
3109
3110
                            # get the value if it exist in the nozebra table, otherwise, create it
3111
                            $sth2->execute( $server, $key, $_ );
3112
                            my $existing_biblionumbers = $sth2->fetchrow;
3113
3114
                            # it exists
3115
                            if ($existing_biblionumbers) {
3116
                                $result{$key}->{"$_"} = $existing_biblionumbers;
3117
                                my $weight = defined $1 ? $1 + 1 : 1;
3118
                                $result{$key}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//g;
3119
                                $result{$key}->{"$_"} .= "$biblionumber,$title-$weight;";
3120
3121
                                # create a new ligne for this entry
3122
                            } else {
3123
3124
                                #                             warn "INSERT : $server / $key / $_";
3125
                                $dbh->do( 'INSERT INTO nozebra SET server=' . $dbh->quote($server) . ', indexname=' . $dbh->quote($key) . ',value=' . $dbh->quote($_) );
3126
                                $result{$key}->{"$_"} .= "$biblionumber,$title-1;";
3127
                            }
3128
                        }
3129
                    }
3130
                }
3131
            }
3132
3133
            # the subfield is not indexed, store it in __RAW__ index anyway
3134
            unless ($indexed) {
3135
                my $line = lc $subfield->[1];
3136
                $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:|\r|\n/ /g;
3137
3138
                # ... and split in words
3139
                foreach ( split / /, $line ) {
3140
                    next unless $_;    # skip  empty values (multiple spaces)
3141
                                       # if the entry is already here, improve weight
3142
                    my $tmpstr = $result{'__RAW__'}->{"$_"} || "";
3143
                    if ( $tmpstr =~ /$biblionumber,\Q$title\E\-(\d+);/ ) {
3144
                        my $weight = $1 + 1;
3145
                        $result{'__RAW__'}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//;
3146
                        $result{'__RAW__'}->{"$_"} .= "$biblionumber,$title-$weight;";
3147
                    } else {
3148
3149
                        # get the value if it exist in the nozebra table, otherwise, create it
3150
                        $sth2->execute( $server, '__RAW__', $_ );
3151
                        my $existing_biblionumbers = $sth2->fetchrow;
3152
3153
                        # it exists
3154
                        if ($existing_biblionumbers) {
3155
                            $result{'__RAW__'}->{"$_"} = $existing_biblionumbers;
3156
                            my $weight = ( $1 ? $1 : 0 ) + 1;
3157
                            $result{'__RAW__'}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//;
3158
                            $result{'__RAW__'}->{"$_"} .= "$biblionumber,$title-$weight;";
3159
3160
                            # create a new ligne for this entry
3161
                        } else {
3162
                            $dbh->do( 'INSERT INTO nozebra SET server=' . $dbh->quote($server) . ',  indexname="__RAW__",value=' . $dbh->quote($_) );
3163
                            $result{'__RAW__'}->{"$_"} .= "$biblionumber,$title-1;";
3164
                        }
3165
                    }
3166
                }
3167
            }
3168
        }
3169
    }
3170
    return %result;
3171
}
3172
3173
=head2 _koha_marc_update_bib_ids
2837
=head2 _koha_marc_update_bib_ids
3174
2838
3175
2839
Lines 3650-3666 sub ModBiblioMarc { Link Here
3650
      $f005->update(sprintf("%4d%02d%02d%02d%02d%04.1f",@a)) if $f005;
3314
      $f005->update(sprintf("%4d%02d%02d%02d%02d%04.1f",@a)) if $f005;
3651
    }
3315
    }
3652
3316
3653
    my $oldRecord;
3654
    if ( C4::Context->preference("NoZebra") ) {
3655
3656
        # only NoZebra indexing needs to have
3657
        # the previous version of the record
3658
        $oldRecord = GetMarcBiblio($biblionumber);
3659
    }
3660
    $sth = $dbh->prepare("UPDATE biblioitems SET marc=?,marcxml=? WHERE biblionumber=?");
3317
    $sth = $dbh->prepare("UPDATE biblioitems SET marc=?,marcxml=? WHERE biblionumber=?");
3661
    $sth->execute( $record->as_usmarc(), $record->as_xml_record($encoding), $biblionumber );
3318
    $sth->execute( $record->as_usmarc(), $record->as_xml_record($encoding), $biblionumber );
3662
    $sth->finish;
3319
    $sth->finish;
3663
    ModZebra( $biblionumber, "specialUpdate", "biblioserver", $oldRecord, $record );
3320
    ModZebra( $biblionumber, "specialUpdate", "biblioserver" );
3664
    return $biblionumber;
3321
    return $biblionumber;
3665
}
3322
}
3666
3323
(-)a/C4/Installer.pm (-26 lines)
Lines 38-44 C4::Installer Link Here
38
 my ($fwk_language, $error_list) = $installer->load_sql_in_order($all_languages, @$list);
38
 my ($fwk_language, $error_list) = $installer->load_sql_in_order($all_languages, @$list);
39
 $installer->set_version_syspref();
39
 $installer->set_version_syspref();
40
 $installer->set_marcflavour_syspref('MARC21');
40
 $installer->set_marcflavour_syspref('MARC21');
41
 $installer->set_indexing_engine(0);
42
41
43
=head1 DESCRIPTION
42
=head1 DESCRIPTION
44
43
Lines 430-460 sub set_marcflavour_syspref { Link Here
430
    $request->execute;
429
    $request->execute;
431
}
430
}
432
431
433
=head2 set_indexing_engine
434
435
  $installer->set_indexing_engine($nozebra);
436
437
Sets system preferences related to the indexing
438
engine.  The C<$nozebra> argument is a boolean;
439
if true, turn on NoZebra mode and turn off QueryFuzzy,
440
QueryWeightFields, and QueryStemming.  If false, turn
441
off NoZebra mode (i.e., use the Zebra search engine).
442
443
=cut
444
445
sub set_indexing_engine {
446
    my $self = shift;
447
    my $nozebra = shift;
448
449
    if ($nozebra) {
450
        $self->{'dbh'}->do("UPDATE systempreferences SET value=1 WHERE variable='NoZebra'");
451
        $self->{'dbh'}->do("UPDATE systempreferences SET value=0 WHERE variable in ('QueryFuzzy','QueryWeightFields','QueryStemming')");
452
    } else {
453
        $self->{'dbh'}->do("UPDATE systempreferences SET value=0 WHERE variable='NoZebra'");
454
    }
455
456
}
457
458
=head2 set_version_syspref
432
=head2 set_version_syspref
459
433
460
  $installer->set_version_syspref();
434
  $installer->set_version_syspref();
(-)a/C4/Items.pm (-17 / +11 lines)
Lines 295-301 sub AddItem { Link Here
295
	my ( $itemnumber, $error ) = _koha_new_item( $item, $item->{barcode} );
295
	my ( $itemnumber, $error ) = _koha_new_item( $item, $item->{barcode} );
296
    $item->{'itemnumber'} = $itemnumber;
296
    $item->{'itemnumber'} = $itemnumber;
297
297
298
    ModZebra( $item->{biblionumber}, "specialUpdate", "biblioserver", undef, undef );
298
    ModZebra( $item->{biblionumber}, "specialUpdate", "biblioserver" );
299
   
299
   
300
    logaction("CATALOGUING", "ADD", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
300
    logaction("CATALOGUING", "ADD", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
301
    
301
    
Lines 549-555 sub ModItem { Link Here
549
549
550
    # request that bib be reindexed so that searching on current
550
    # request that bib be reindexed so that searching on current
551
    # item status is possible
551
    # item status is possible
552
    ModZebra( $biblionumber, "specialUpdate", "biblioserver", undef, undef );
552
    ModZebra( $biblionumber, "specialUpdate", "biblioserver" );
553
553
554
    logaction("CATALOGUING", "MODIFY", $itemnumber, Dumper($item)) if C4::Context->preference("CataloguingLog");
554
    logaction("CATALOGUING", "MODIFY", $itemnumber, Dumper($item)) if C4::Context->preference("CataloguingLog");
555
}
555
}
Lines 615-621 sub DelItem { Link Here
615
615
616
    # get the MARC record
616
    # get the MARC record
617
    my $record = GetMarcBiblio($biblionumber);
617
    my $record = GetMarcBiblio($biblionumber);
618
    ModZebra( $biblionumber, "specialUpdate", "biblioserver", undef, undef );
618
    ModZebra( $biblionumber, "specialUpdate", "biblioserver" );
619
619
620
    # backup the record
620
    # backup the record
621
    my $copy2deleted = $dbh->prepare("UPDATE deleteditems SET marc=? WHERE itemnumber=?");
621
    my $copy2deleted = $dbh->prepare("UPDATE deleteditems SET marc=? WHERE itemnumber=?");
Lines 2173-2180 sub MoveItemFromBiblio { Link Here
2173
    $sth = $dbh->prepare("UPDATE items SET biblioitemnumber = ?, biblionumber = ? WHERE itemnumber = ? AND biblionumber = ?");
2173
    $sth = $dbh->prepare("UPDATE items SET biblioitemnumber = ?, biblionumber = ? WHERE itemnumber = ? AND biblionumber = ?");
2174
    my $return = $sth->execute($tobiblioitem, $tobiblio, $itemnumber, $frombiblio);
2174
    my $return = $sth->execute($tobiblioitem, $tobiblio, $itemnumber, $frombiblio);
2175
    if ($return == 1) {
2175
    if ($return == 1) {
2176
        ModZebra( $tobiblio, "specialUpdate", "biblioserver", undef, undef );
2176
        ModZebra( $tobiblio, "specialUpdate", "biblioserver" );
2177
        ModZebra( $frombiblio, "specialUpdate", "biblioserver", undef, undef );
2177
        ModZebra( $frombiblio, "specialUpdate", "biblioserver" );
2178
	    # Checking if the item we want to move is in an order 
2178
	    # Checking if the item we want to move is in an order 
2179
        require C4::Acquisition;
2179
        require C4::Acquisition;
2180
        my $order = C4::Acquisition::GetOrderFromItemnumber($itemnumber);
2180
        my $order = C4::Acquisition::GetOrderFromItemnumber($itemnumber);
Lines 2460-2477 counts Usage of itemnumber in Analytical bibliorecords. Link Here
2460
sub GetAnalyticsCount {
2460
sub GetAnalyticsCount {
2461
    my ($itemnumber) = @_;
2461
    my ($itemnumber) = @_;
2462
    require C4::Search;
2462
    require C4::Search;
2463
    if (C4::Context->preference('NoZebra')) {
2463
2464
        # Read the index Koha-Auth-Number for this authid and count the lines
2464
    ### ZOOM search here
2465
        my $result = C4::Search::NZanalyse("hi=$itemnumber");
2465
    my $query;
2466
        my @tab = split /;/,$result;
2466
    $query= "hi=".$itemnumber;
2467
        return scalar @tab;
2467
            my ($err,$res,$result) = C4::Search::SimpleSearch($query,0,10);
2468
    } else {
2468
    return ($result);
2469
        ### ZOOM search here
2470
        my $query;
2471
        $query= "hi=".$itemnumber;
2472
                my ($err,$res,$result) = C4::Search::SimpleSearch($query,0,10);
2473
        return ($result);
2474
    }
2475
}
2469
}
2476
2470
2477
=head2 GetItemHolds
2471
=head2 GetItemHolds
(-)a/C4/Search.pm (-672 / +58 lines)
Lines 68-74 This module provides searching functions for Koha's bibliographic databases Link Here
68
  &searchResults
68
  &searchResults
69
  &getRecords
69
  &getRecords
70
  &buildQuery
70
  &buildQuery
71
  &NZgetRecords
72
  &AddSearchHistory
71
  &AddSearchHistory
73
  &GetDistinctValues
72
  &GetDistinctValues
74
  &enabled_staff_search_views
73
  &enabled_staff_search_views
Lines 207-286 $template->param(result=>\@results); Link Here
207
sub SimpleSearch {
206
sub SimpleSearch {
208
    my ( $query, $offset, $max_results, $servers )  = @_;
207
    my ( $query, $offset, $max_results, $servers )  = @_;
209
208
210
    if ( C4::Context->preference('NoZebra') ) {
209
    return ( 'No query entered', undef, undef ) unless $query;
211
        my $result = NZorder( NZanalyse($query) )->{'biblioserver'};
210
    # FIXME hardcoded value. See catalog/search.pl & opac-search.pl too.
212
        my $search_result =
211
    my @servers = defined ( $servers ) ? @$servers : ( 'biblioserver' );
213
          (      $result->{hits}
212
    my @zoom_queries;
214
              && $result->{hits} > 0 ? $result->{'RECORDS'} : [] );
213
    my @tmpresults;
215
        return ( undef, $search_result, scalar($result->{hits}) );
214
    my @zconns;
216
    }
215
    my $results = [];
217
    else {
216
    my $total_hits = 0;
218
        return ( 'No query entered', undef, undef ) unless $query;
219
        # FIXME hardcoded value. See catalog/search.pl & opac-search.pl too.
220
        my @servers = defined ( $servers ) ? @$servers : ( 'biblioserver' );
221
        my @zoom_queries;
222
        my @tmpresults;
223
        my @zconns;
224
        my $results = [];
225
        my $total_hits = 0;
226
227
        # Initialize & Search Zebra
228
        for ( my $i = 0 ; $i < @servers ; $i++ ) {
229
            eval {
230
                $zconns[$i] = C4::Context->Zconn( $servers[$i], 1 );
231
                $zoom_queries[$i] = new ZOOM::Query::CCL2RPN( $query, $zconns[$i]);
232
                $tmpresults[$i] = $zconns[$i]->search( $zoom_queries[$i] );
233
234
                # error handling
235
                my $error =
236
                    $zconns[$i]->errmsg() . " ("
237
                  . $zconns[$i]->errcode() . ") "
238
                  . $zconns[$i]->addinfo() . " "
239
                  . $zconns[$i]->diagset();
240
241
                return ( $error, undef, undef ) if $zconns[$i]->errcode();
242
            };
243
            if ($@) {
244
245
                # caught a ZOOM::Exception
246
                my $error =
247
                    $@->message() . " ("
248
                  . $@->code() . ") "
249
                  . $@->addinfo() . " "
250
                  . $@->diagset();
251
                warn $error." for query: $query";
252
                return ( $error, undef, undef );
253
            }
254
        }
255
217
256
        _ZOOM_event_loop(
218
    # Initialize & Search Zebra
257
            \@zconns,
219
    for ( my $i = 0 ; $i < @servers ; $i++ ) {
258
            \@tmpresults,
220
        eval {
259
            sub {
221
            $zconns[$i] = C4::Context->Zconn( $servers[$i], 1 );
260
                my ($i, $size) = @_;
222
            $zoom_queries[$i] = new ZOOM::Query::CCL2RPN( $query, $zconns[$i]);
261
                my $first_record = defined($offset) ? $offset + 1 : 1;
223
            $tmpresults[$i] = $zconns[$i]->search( $zoom_queries[$i] );
262
                my $hits = $tmpresults[ $i - 1 ]->size();
224
263
                $total_hits += $hits;
225
            # error handling
264
                my $last_record = $hits;
226
            my $error =
265
                if ( defined $max_results && $offset + $max_results < $hits ) {
227
                $zconns[$i]->errmsg() . " ("
266
                    $last_record = $offset + $max_results;
228
              . $zconns[$i]->errcode() . ") "
267
                }
229
              . $zconns[$i]->addinfo() . " "
230
              . $zconns[$i]->diagset();
231
232
            return ( $error, undef, undef ) if $zconns[$i]->errcode();
233
        };
234
        if ($@) {
268
235
269
                for my $j ( $first_record .. $last_record ) {
236
            # caught a ZOOM::Exception
270
                    my $record =
237
            my $error =
271
                      $tmpresults[ $i - 1 ]->record( $j - 1 )->raw()
238
                $@->message() . " ("
272
                      ;    # 0 indexed
239
              . $@->code() . ") "
273
                    push @{$results}, $record;
240
              . $@->addinfo() . " "
274
                }
241
              . $@->diagset();
242
            warn $error." for query: $query";
243
            return ( $error, undef, undef );
244
        }
245
    }
246
247
    _ZOOM_event_loop(
248
        \@zconns,
249
        \@tmpresults,
250
        sub {
251
            my ($i, $size) = @_;
252
            my $first_record = defined($offset) ? $offset + 1 : 1;
253
            my $hits = $tmpresults[ $i - 1 ]->size();
254
            $total_hits += $hits;
255
            my $last_record = $hits;
256
            if ( defined $max_results && $offset + $max_results < $hits ) {
257
                $last_record = $offset + $max_results;
275
            }
258
            }
276
        );
277
259
278
        foreach my $zoom_query (@zoom_queries) {
260
            for my $j ( $first_record .. $last_record ) {
279
            $zoom_query->destroy();
261
                my $record =
262
                  $tmpresults[ $i - 1 ]->record( $j - 1 )->raw()
263
                  ;    # 0 indexed
264
                push @{$results}, $record;
265
            }
280
        }
266
        }
267
    );
281
268
282
        return ( undef, $results, $total_hits );
269
    foreach my $zoom_query (@zoom_queries) {
270
        $zoom_query->destroy();
283
    }
271
    }
272
273
    return ( undef, $results, $total_hits );
284
}
274
}
285
275
286
=head2 getRecords
276
=head2 getRecords
Lines 1214-1227 sub buildQuery { Link Here
1214
    my $fuzzy_enabled    = C4::Context->preference("QueryFuzzy")           || 0;
1204
    my $fuzzy_enabled    = C4::Context->preference("QueryFuzzy")           || 0;
1215
    my $remove_stopwords = C4::Context->preference("QueryRemoveStopwords") || 0;
1205
    my $remove_stopwords = C4::Context->preference("QueryRemoveStopwords") || 0;
1216
1206
1217
    # no stemming/weight/fuzzy in NoZebra
1218
    if ( C4::Context->preference("NoZebra") ) {
1219
        $stemming         = 0;
1220
        $weight_fields    = 0;
1221
        $fuzzy_enabled    = 0;
1222
    	$auto_truncation  = 0;
1223
    }
1224
1225
    my $query        = $operands[0];
1207
    my $query        = $operands[0];
1226
    my $simple_query = $operands[0];
1208
    my $simple_query = $operands[0];
1227
1209
Lines 2114-2715 sub SearchAcquisitions{ Link Here
2114
    $qdataacquisitions->finish;
2096
    $qdataacquisitions->finish;
2115
    return \@loopacquisitions;
2097
    return \@loopacquisitions;
2116
}
2098
}
2117
#----------------------------------------------------------------------
2118
#
2119
# Non-Zebra GetRecords#
2120
#----------------------------------------------------------------------
2121
2122
=head2 NZgetRecords
2123
2124
  NZgetRecords has the same API as zera getRecords, even if some parameters are not managed
2125
2126
=cut
2127
2128
sub NZgetRecords {
2129
    my (
2130
        $query,            $simple_query, $sort_by_ref,    $servers_ref,
2131
        $results_per_page, $offset,       $expanded_facet, $branches,
2132
        $query_type,       $scan
2133
    ) = @_;
2134
    warn "query =$query" if $DEBUG;
2135
    my $result = NZanalyse($query);
2136
    warn "results =$result" if $DEBUG;
2137
    return ( undef,
2138
        NZorder( $result, @$sort_by_ref[0], $results_per_page, $offset ),
2139
        undef );
2140
}
2141
2142
=head2 NZanalyse
2143
2144
  NZanalyse : get a CQL string as parameter, and returns a list of biblionumber;title,biblionumber;title,...
2145
  the list is built from an inverted index in the nozebra SQL table
2146
  note that title is here only for convenience : the sorting will be very fast when requested on title
2147
  if the sorting is requested on something else, we will have to reread all results, and that may be longer.
2148
2149
=cut
2150
2151
sub NZanalyse {
2152
    my ( $string, $server ) = @_;
2153
#     warn "---------"       if $DEBUG;
2154
    warn " NZanalyse" if $DEBUG;
2155
#     warn "---------"       if $DEBUG;
2156
2157
 # $server contains biblioserver or authorities, depending on what we search on.
2158
 #warn "querying : $string on $server";
2159
    $server = 'biblioserver' unless $server;
2160
2161
# if we have a ", replace the content to discard temporarily any and/or/not inside
2162
    my $commacontent;
2163
    if ( $string =~ /"/ ) {
2164
        $string =~ s/"(.*?)"/__X__/;
2165
        $commacontent = $1;
2166
        warn "commacontent : $commacontent" if $DEBUG;
2167
    }
2168
2169
# split the query string in 3 parts : X AND Y means : $left="X", $operand="AND" and $right="Y"
2170
# then, call again NZanalyse with $left and $right
2171
# (recursive until we find a leaf (=> something without and/or/not)
2172
# delete repeated operator... Would then go in infinite loop
2173
    while ( $string =~ s/( and| or| not| AND| OR| NOT)\1/$1/g ) {
2174
    }
2175
2176
    #process parenthesis before.
2177
    if ( $string =~ /^\s*\((.*)\)(( and | or | not | AND | OR | NOT )(.*))?/ ) {
2178
        my $left     = $1;
2179
        my $right    = $4;
2180
        my $operator = lc($3);   # FIXME: and/or/not are operators, not operands
2181
        warn
2182
"dealing w/parenthesis before recursive sub call. left :$left operator:$operator right:$right"
2183
          if $DEBUG;
2184
        my $leftresult = NZanalyse( $left, $server );
2185
        if ($operator) {
2186
            my $rightresult = NZanalyse( $right, $server );
2187
2188
            # OK, we have the results for right and left part of the query
2189
            # depending of operand, intersect, union or exclude both lists
2190
            # to get a result list
2191
            if ( $operator eq ' and ' ) {
2192
                return NZoperatorAND($leftresult,$rightresult);
2193
            }
2194
            elsif ( $operator eq ' or ' ) {
2195
2196
                # just merge the 2 strings
2197
                return $leftresult . $rightresult;
2198
            }
2199
            elsif ( $operator eq ' not ' ) {
2200
                return NZoperatorNOT($leftresult,$rightresult);
2201
            }
2202
        }
2203
        else {
2204
# this error is impossible, because of the regexp that isolate the operand, but just in case...
2205
            return $leftresult;
2206
        }
2207
    }
2208
    warn "string :" . $string if $DEBUG;
2209
    my $left = "";
2210
    my $right = "";
2211
    my $operator = "";
2212
    if ($string =~ /(.*?)( and | or | not | AND | OR | NOT )(.*)/) {
2213
        $left     = $1;
2214
        $right    = $3;
2215
        $operator = lc($2);    # FIXME: and/or/not are operators, not operands
2216
    }
2217
    warn "no parenthesis. left : $left operator: $operator right: $right"
2218
      if $DEBUG;
2219
2220
    # it's not a leaf, we have a and/or/not
2221
    if ($operator) {
2222
2223
        # reintroduce comma content if needed
2224
        $right =~ s/__X__/"$commacontent"/ if $commacontent;
2225
        $left  =~ s/__X__/"$commacontent"/ if $commacontent;
2226
        warn "node : $left / $operator / $right\n" if $DEBUG;
2227
        my $leftresult  = NZanalyse( $left,  $server );
2228
        my $rightresult = NZanalyse( $right, $server );
2229
        warn " leftresult : $leftresult" if $DEBUG;
2230
        warn " rightresult : $rightresult" if $DEBUG;
2231
        # OK, we have the results for right and left part of the query
2232
        # depending of operand, intersect, union or exclude both lists
2233
        # to get a result list
2234
        if ( $operator eq ' and ' ) {
2235
            return NZoperatorAND($leftresult,$rightresult);
2236
        }
2237
        elsif ( $operator eq ' or ' ) {
2238
2239
            # just merge the 2 strings
2240
            return $leftresult . $rightresult;
2241
        }
2242
        elsif ( $operator eq ' not ' ) {
2243
            return NZoperatorNOT($leftresult,$rightresult);
2244
        }
2245
        else {
2246
2247
# this error is impossible, because of the regexp that isolate the operand, but just in case...
2248
            die "error : operand unknown : $operator for $string";
2249
        }
2250
2251
        # it's a leaf, do the real SQL query and return the result
2252
    }
2253
    else {
2254
        $string =~ s/__X__/"$commacontent"/ if $commacontent;
2255
        $string =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|&|\+|\*|\// /g;
2256
        #remove trailing blank at the beginning
2257
        $string =~ s/^ //g;
2258
        warn "leaf:$string" if $DEBUG;
2259
2260
        # parse the string in in operator/operand/value again
2261
        my $left = "";
2262
        my $operator = "";
2263
        my $right = "";
2264
        if ($string =~ /(.*)(>=|<=)(.*)/) {
2265
            $left     = $1;
2266
            $operator = $2;
2267
            $right    = $3;
2268
        } else {
2269
            $left = $string;
2270
        }
2271
#         warn "handling leaf... left:$left operator:$operator right:$right"
2272
#           if $DEBUG;
2273
        unless ($operator) {
2274
            if ($string =~ /(.*)(>|<|=)(.*)/) {
2275
                $left     = $1;
2276
                $operator = $2;
2277
                $right    = $3;
2278
                warn
2279
    "handling unless (operator)... left:$left operator:$operator right:$right"
2280
                if $DEBUG;
2281
            } else {
2282
                $left = $string;
2283
            }
2284
        }
2285
        my $results;
2286
2287
# strip adv, zebra keywords, currently not handled in nozebra: wrdl, ext, phr...
2288
        $left =~ s/ .*$//;
2289
2290
        # automatic replace for short operators
2291
        $left = 'title'            if $left =~ '^ti$';
2292
        $left = 'author'           if $left =~ '^au$';
2293
        $left = 'publisher'        if $left =~ '^pb$';
2294
        $left = 'subject'          if $left =~ '^su$';
2295
        $left = 'koha-Auth-Number' if $left =~ '^an$';
2296
        $left = 'keyword'          if $left =~ '^kw$';
2297
        $left = 'itemtype'         if $left =~ '^mc$'; # Fix for Bug 2599 - Search limits not working for NoZebra
2298
        warn "handling leaf... left:$left operator:$operator right:$right" if $DEBUG;
2299
        my $dbh = C4::Context->dbh;
2300
        if ( $operator && $left ne 'keyword' ) {
2301
            #do a specific search
2302
            $operator = 'LIKE' if $operator eq '=' and $right =~ /%/;
2303
            my $sth = $dbh->prepare(
2304
"SELECT biblionumbers,value FROM nozebra WHERE server=? AND indexname=? AND value $operator ?"
2305
            );
2306
            warn "$left / $operator / $right\n" if $DEBUG;
2307
2308
            # split each word, query the DB and build the biblionumbers result
2309
            #sanitizing leftpart
2310
            $left =~ s/^\s+|\s+$//;
2311
            foreach ( split / /, $right ) {
2312
                my $biblionumbers;
2313
                $_ =~ s/^\s+|\s+$//;
2314
                next unless $_;
2315
                warn "EXECUTE : $server, $left, $_" if $DEBUG;
2316
                $sth->execute( $server, $left, $_ )
2317
                  or warn "execute failed: $!";
2318
                while ( my ( $line, $value ) = $sth->fetchrow ) {
2319
2320
# if we are dealing with a numeric value, use only numeric results (in case of >=, <=, > or <)
2321
# otherwise, fill the result
2322
                    $biblionumbers .= $line
2323
                      unless ( $right =~ /^\d+$/ && $value =~ /\D/ );
2324
                    warn "result : $value "
2325
                      . ( $right  =~ /\d/ ) . "=="
2326
                      . ( $value =~ /\D/?$line:"" ) if $DEBUG;         #= $line";
2327
                }
2328
2329
# do a AND with existing list if there is one, otherwise, use the biblionumbers list as 1st result list
2330
                if ($results) {
2331
                    warn "NZAND" if $DEBUG;
2332
                    $results = NZoperatorAND($biblionumbers,$results);
2333
                } else {
2334
                    $results = $biblionumbers;
2335
                }
2336
            }
2337
        }
2338
        else {
2339
      #do a complete search (all indexes), if index='kw' do complete search too.
2340
            my $sth = $dbh->prepare(
2341
"SELECT biblionumbers FROM nozebra WHERE server=? AND value LIKE ?"
2342
            );
2343
2344
            # split each word, query the DB and build the biblionumbers result
2345
            foreach ( split / /, $string ) {
2346
                next if C4::Context->stopwords->{ uc($_) };   # skip if stopword
2347
                warn "search on all indexes on $_" if $DEBUG;
2348
                my $biblionumbers;
2349
                next unless $_;
2350
                $sth->execute( $server, $_ );
2351
                while ( my $line = $sth->fetchrow ) {
2352
                    $biblionumbers .= $line;
2353
                }
2354
2355
# do a AND with existing list if there is one, otherwise, use the biblionumbers list as 1st result list
2356
                if ($results) {
2357
                    $results = NZoperatorAND($biblionumbers,$results);
2358
                }
2359
                else {
2360
                    warn "NEW RES for $_ = $biblionumbers" if $DEBUG;
2361
                    $results = $biblionumbers;
2362
                }
2363
            }
2364
        }
2365
        warn "return : $results for LEAF : $string" if $DEBUG;
2366
        return $results;
2367
    }
2368
    warn "---------\nLeave NZanalyse\n---------" if $DEBUG;
2369
}
2370
2371
sub NZoperatorAND{
2372
    my ($rightresult, $leftresult)=@_;
2373
2374
    my @leftresult = split /;/, $leftresult;
2375
    warn " @leftresult / $rightresult \n" if $DEBUG;
2376
2377
    #             my @rightresult = split /;/,$leftresult;
2378
    my $finalresult;
2379
2380
# parse the left results, and if the biblionumber exist in the right result, save it in finalresult
2381
# the result is stored twice, to have the same weight for AND than OR.
2382
# example : TWO : 61,61,64,121 (two is twice in the biblio #61) / TOWER : 61,64,130
2383
# result : 61,61,61,61,64,64 for two AND tower : 61 has more weight than 64
2384
    foreach (@leftresult) {
2385
        my $value = $_;
2386
        my $countvalue;
2387
        ( $value, $countvalue ) = ( $1, $2 ) if ($value=~/(.*)-(\d+)$/);
2388
        if ( $rightresult =~ /\Q$value\E-(\d+);/ ) {
2389
            $countvalue = ( $1 > $countvalue ? $countvalue : $1 );
2390
            $finalresult .=
2391
                "$value-$countvalue;$value-$countvalue;";
2392
        }
2393
    }
2394
    warn "NZAND DONE : $finalresult \n" if $DEBUG;
2395
    return $finalresult;
2396
}
2397
2398
sub NZoperatorOR{
2399
    my ($rightresult, $leftresult)=@_;
2400
    return $rightresult.$leftresult;
2401
}
2402
2403
sub NZoperatorNOT{
2404
    my ($leftresult, $rightresult)=@_;
2405
2406
    my @leftresult = split /;/, $leftresult;
2407
2408
    #             my @rightresult = split /;/,$leftresult;
2409
    my $finalresult;
2410
    foreach (@leftresult) {
2411
        my $value=$_;
2412
        $value=$1 if $value=~m/(.*)-\d+$/;
2413
        unless ($rightresult =~ "$value-") {
2414
            $finalresult .= "$_;";
2415
        }
2416
    }
2417
    return $finalresult;
2418
}
2419
2420
=head2 NZorder
2421
2422
  $finalresult = NZorder($biblionumbers, $ordering,$results_per_page,$offset);
2423
2424
  TODO :: Description
2425
2426
=cut
2427
2428
sub NZorder {
2429
    my ( $biblionumbers, $ordering, $results_per_page, $offset ) = @_;
2430
    warn "biblionumbers = $biblionumbers and ordering = $ordering\n" if $DEBUG;
2431
2432
    # order title asc by default
2433
    #     $ordering = '1=36 <i' unless $ordering;
2434
    $results_per_page = 20 unless $results_per_page;
2435
    $offset           = 0  unless $offset;
2436
    my $dbh = C4::Context->dbh;
2437
2438
    #
2439
    # order by POPULARITY
2440
    #
2441
    if ( $ordering =~ /popularity/ ) {
2442
        my %result;
2443
        my %popularity;
2444
2445
        # popularity is not in MARC record, it's builded from a specific query
2446
        my $sth =
2447
          $dbh->prepare("select sum(issues) from items where biblionumber=?");
2448
        foreach ( split /;/, $biblionumbers ) {
2449
            my ( $biblionumber, $title ) = split /,/, $_;
2450
            $result{$biblionumber} = GetMarcBiblio($biblionumber);
2451
            $sth->execute($biblionumber);
2452
            my $popularity = $sth->fetchrow || 0;
2453
2454
# hint : the key is popularity.title because we can have
2455
# many results with the same popularity. In this case, sub-ordering is done by title
2456
# we also have biblionumber to avoid bug for 2 biblios with the same title & popularity
2457
# (un-frequent, I agree, but we won't forget anything that way ;-)
2458
            $popularity{ sprintf( "%10d", $popularity ) . $title
2459
                  . $biblionumber } = $biblionumber;
2460
        }
2461
2462
    # sort the hash and return the same structure as GetRecords (Zebra querying)
2463
        my $result_hash;
2464
        my $numbers = 0;
2465
        if ( $ordering eq 'popularity_dsc' ) {    # sort popularity DESC
2466
            foreach my $key ( sort { $b cmp $a } ( keys %popularity ) ) {
2467
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2468
                  $result{ $popularity{$key} }->as_usmarc();
2469
            }
2470
        }
2471
        else {                                    # sort popularity ASC
2472
            foreach my $key ( sort ( keys %popularity ) ) {
2473
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2474
                  $result{ $popularity{$key} }->as_usmarc();
2475
            }
2476
        }
2477
        my $finalresult = ();
2478
        $result_hash->{'hits'}         = $numbers;
2479
        $finalresult->{'biblioserver'} = $result_hash;
2480
        return $finalresult;
2481
2482
        #
2483
        # ORDER BY author
2484
        #
2485
    }
2486
    elsif ( $ordering =~ /author/ ) {
2487
        my %result;
2488
        foreach ( split /;/, $biblionumbers ) {
2489
            my ( $biblionumber, $title ) = split /,/, $_;
2490
            my $record = GetMarcBiblio($biblionumber);
2491
            my $author;
2492
            if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
2493
                $author = $record->subfield( '200', 'f' );
2494
                $author = $record->subfield( '700', 'a' ) unless $author;
2495
            }
2496
            else {
2497
                $author = $record->subfield( '100', 'a' );
2498
            }
2499
2500
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
2501
# and we don't want to get only 1 result for each of them !!!
2502
            $result{ $author . $biblionumber } = $record;
2503
        }
2504
2505
    # sort the hash and return the same structure as GetRecords (Zebra querying)
2506
        my $result_hash;
2507
        my $numbers = 0;
2508
        if ( $ordering eq 'author_za' || $ordering eq 'author_dsc' ) {    # sort by author desc
2509
            foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
2510
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2511
                  $result{$key}->as_usmarc();
2512
            }
2513
        }
2514
        else {                               # sort by author ASC
2515
            foreach my $key ( sort ( keys %result ) ) {
2516
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2517
                  $result{$key}->as_usmarc();
2518
            }
2519
        }
2520
        my $finalresult = ();
2521
        $result_hash->{'hits'}         = $numbers;
2522
        $finalresult->{'biblioserver'} = $result_hash;
2523
        return $finalresult;
2524
2525
        #
2526
        # ORDER BY callnumber
2527
        #
2528
    }
2529
    elsif ( $ordering =~ /callnumber/ ) {
2530
        my %result;
2531
        foreach ( split /;/, $biblionumbers ) {
2532
            my ( $biblionumber, $title ) = split /,/, $_;
2533
            my $record = GetMarcBiblio($biblionumber);
2534
            my $callnumber;
2535
            my $frameworkcode = GetFrameworkCode($biblionumber);
2536
            my ( $callnumber_tag, $callnumber_subfield ) = GetMarcFromKohaField(  'items.itemcallnumber', $frameworkcode);
2537
               ( $callnumber_tag, $callnumber_subfield ) = GetMarcFromKohaField('biblioitems.callnumber', $frameworkcode)
2538
                unless $callnumber_tag;
2539
            if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
2540
                $callnumber = $record->subfield( '200', 'f' );
2541
            } else {
2542
                $callnumber = $record->subfield( '100', 'a' );
2543
            }
2544
2545
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
2546
# and we don't want to get only 1 result for each of them !!!
2547
            $result{ $callnumber . $biblionumber } = $record;
2548
        }
2549
2550
    # sort the hash and return the same structure as GetRecords (Zebra querying)
2551
        my $result_hash;
2552
        my $numbers = 0;
2553
        if ( $ordering eq 'call_number_dsc' ) {    # sort by title desc
2554
            foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
2555
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2556
                  $result{$key}->as_usmarc();
2557
            }
2558
        }
2559
        else {                                     # sort by title ASC
2560
            foreach my $key ( sort { $a cmp $b } ( keys %result ) ) {
2561
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2562
                  $result{$key}->as_usmarc();
2563
            }
2564
        }
2565
        my $finalresult = ();
2566
        $result_hash->{'hits'}         = $numbers;
2567
        $finalresult->{'biblioserver'} = $result_hash;
2568
        return $finalresult;
2569
    }
2570
    elsif ( $ordering =~ /pubdate/ ) {             #pub year
2571
        my %result;
2572
        foreach ( split /;/, $biblionumbers ) {
2573
            my ( $biblionumber, $title ) = split /,/, $_;
2574
            my $record = GetMarcBiblio($biblionumber);
2575
            my ( $publicationyear_tag, $publicationyear_subfield ) =
2576
              GetMarcFromKohaField( 'biblioitems.publicationyear', '' );
2577
            my $publicationyear =
2578
              $record->subfield( $publicationyear_tag,
2579
                $publicationyear_subfield );
2580
2581
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
2582
# and we don't want to get only 1 result for each of them !!!
2583
            $result{ $publicationyear . $biblionumber } = $record;
2584
        }
2585
2586
    # sort the hash and return the same structure as GetRecords (Zebra querying)
2587
        my $result_hash;
2588
        my $numbers = 0;
2589
        if ( $ordering eq 'pubdate_dsc' ) {    # sort by pubyear desc
2590
            foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
2591
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2592
                  $result{$key}->as_usmarc();
2593
            }
2594
        }
2595
        else {                                 # sort by pub year ASC
2596
            foreach my $key ( sort ( keys %result ) ) {
2597
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2598
                  $result{$key}->as_usmarc();
2599
            }
2600
        }
2601
        my $finalresult = ();
2602
        $result_hash->{'hits'}         = $numbers;
2603
        $finalresult->{'biblioserver'} = $result_hash;
2604
        return $finalresult;
2605
2606
        #
2607
        # ORDER BY title
2608
        #
2609
    }
2610
    elsif ( $ordering =~ /title/ ) {
2611
2612
# the title is in the biblionumbers string, so we just need to build a hash, sort it and return
2613
        my %result;
2614
        foreach ( split /;/, $biblionumbers ) {
2615
            my ( $biblionumber, $title ) = split /,/, $_;
2616
2617
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
2618
# and we don't want to get only 1 result for each of them !!!
2619
# hint & speed improvement : we can order without reading the record
2620
# so order, and read records only for the requested page !
2621
            $result{ $title . $biblionumber } = $biblionumber;
2622
        }
2623
2624
    # sort the hash and return the same structure as GetRecords (Zebra querying)
2625
        my $result_hash;
2626
        my $numbers = 0;
2627
        if ( $ordering eq 'title_az' ) {    # sort by title desc
2628
            foreach my $key ( sort ( keys %result ) ) {
2629
                $result_hash->{'RECORDS'}[ $numbers++ ] = $result{$key};
2630
            }
2631
        }
2632
        else {                              # sort by title ASC
2633
            foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
2634
                $result_hash->{'RECORDS'}[ $numbers++ ] = $result{$key};
2635
            }
2636
        }
2637
2638
        # limit the $results_per_page to result size if it's more
2639
        $results_per_page = $numbers - 1 if $numbers < $results_per_page;
2640
2641
        # for the requested page, replace biblionumber by the complete record
2642
        # speed improvement : avoid reading too much things
2643
        for (
2644
            my $counter = $offset ;
2645
            $counter <= $offset + $results_per_page ;
2646
            $counter++
2647
          )
2648
        {
2649
            $result_hash->{'RECORDS'}[$counter] =
2650
              GetMarcBiblio( $result_hash->{'RECORDS'}[$counter] )->as_usmarc;
2651
        }
2652
        my $finalresult = ();
2653
        $result_hash->{'hits'}         = $numbers;
2654
        $finalresult->{'biblioserver'} = $result_hash;
2655
        return $finalresult;
2656
    }
2657
    else {
2658
2659
#
2660
# order by ranking
2661
#
2662
# we need 2 hashes to order by ranking : the 1st one to count the ranking, the 2nd to order by ranking
2663
        my %result;
2664
        my %count_ranking;
2665
        foreach ( split /;/, $biblionumbers ) {
2666
            my ( $biblionumber, $title ) = split /,/, $_;
2667
            $title =~ /(.*)-(\d)/;
2668
2669
            # get weight
2670
            my $ranking = $2;
2671
2672
# note that we + the ranking because ranking is calculated on weight of EACH term requested.
2673
# if we ask for "two towers", and "two" has weight 2 in biblio N, and "towers" has weight 4 in biblio N
2674
# biblio N has ranking = 6
2675
            $count_ranking{$biblionumber} += $ranking;
2676
        }
2677
2678
# build the result by "inverting" the count_ranking hash
2679
# hing : as usual, we don't order by ranking only, to avoid having only 1 result for each rank. We build an hash on concat(ranking,biblionumber) instead
2680
#         warn "counting";
2681
        foreach ( keys %count_ranking ) {
2682
            $result{ sprintf( "%10d", $count_ranking{$_} ) . '-' . $_ } = $_;
2683
        }
2684
2685
    # sort the hash and return the same structure as GetRecords (Zebra querying)
2686
        my $result_hash;
2687
        my $numbers = 0;
2688
        foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
2689
            $result_hash->{'RECORDS'}[ $numbers++ ] = $result{$key};
2690
        }
2691
2692
        # limit the $results_per_page to result size if it's more
2693
        $results_per_page = $numbers - 1 if $numbers < $results_per_page;
2694
2695
        # for the requested page, replace biblionumber by the complete record
2696
        # speed improvement : avoid reading too much things
2697
        for (
2698
            my $counter = $offset ;
2699
            $counter <= $offset + $results_per_page ;
2700
            $counter++
2701
          )
2702
        {
2703
            $result_hash->{'RECORDS'}[$counter] =
2704
              GetMarcBiblio( $result_hash->{'RECORDS'}[$counter] )->as_usmarc
2705
              if $result_hash->{'RECORDS'}[$counter];
2706
        }
2707
        my $finalresult = ();
2708
        $result_hash->{'hits'}         = $numbers;
2709
        $finalresult->{'biblioserver'} = $result_hash;
2710
        return $finalresult;
2711
    }
2712
}
2713
2099
2714
=head2 enabled_staff_search_views
2100
=head2 enabled_staff_search_views
2715
2101
(-)a/INSTALL.fedora7 (-2 / +1 lines)
Lines 1169-1175 MySQL> show tables; Link Here
1169
| matchpoint_components |
1169
| matchpoint_components |
1170
| matchpoints |
1170
| matchpoints |
1171
| notifys |
1171
| notifys |
1172
| nozebra |
1173
| opac_news |
1172
| opac_news |
1174
| overduerules |
1173
| overduerules |
1175
| printers |
1174
| printers |
Lines 1258-1264 Connect to Koha: HYPERLINK "http://localhost:8080/" http://localhost:8080 and us Link Here
1258
-- A Phase 3, click on Install the basic settings (screen 1), select the declination Marc (Unimarc_complet in our
1257
-- A Phase 3, click on Install the basic settings (screen 1), select the declination Marc (Unimarc_complet in our
1259
Where Unimarc_lecture_pub; screen 2), select default settings and then click on Import (only settings obligat
1258
Where Unimarc_lecture_pub; screen 2), select default settings and then click on Import (only settings obligat
1260
oires are checked by default; screen 3);
1259
oires are checked by default; screen 3);
1261
-- The screen 4 summarizes what has been imported, while low demand to opt for a configuration Zebra (our choice) or NoZebra;
1260
-- The screen 4 summarizes what has been imported;
1262
-- Finally, the screen 5 indicates the end of the installation; then you just have to click Finish.
1261
-- Finally, the screen 5 indicates the end of the installation; then you just have to click Finish.
1263
1262
1264
Complements
1263
Complements
(-)a/about.pl (-2 lines)
Lines 61-67 $apacheVersion = (`/usr/sbin/apache2 -V`)[0] unless $apacheVersion; Link Here
61
my $zebraVersion = `zebraidx -V`;
61
my $zebraVersion = `zebraidx -V`;
62
62
63
# Additional system information for warnings
63
# Additional system information for warnings
64
my $prefNoZebra = C4::Context->preference('nozebra');
65
my $prefAutoCreateAuthorities = C4::Context->preference('AutoCreateAuthorities');
64
my $prefAutoCreateAuthorities = C4::Context->preference('AutoCreateAuthorities');
66
my $prefBiblioAddsAuthorities = C4::Context->preference('BiblioAddsAuthorities');
65
my $prefBiblioAddsAuthorities = C4::Context->preference('BiblioAddsAuthorities');
67
my $warnPrefBiblioAddsAuthorities = ( $prefAutoCreateAuthorities && ( !$prefBiblioAddsAuthorities) );
66
my $warnPrefBiblioAddsAuthorities = ( $prefAutoCreateAuthorities && ( !$prefBiblioAddsAuthorities) );
Lines 83-89 $template->param( Link Here
83
    mysqlVersion  => $mysqlVersion,
82
    mysqlVersion  => $mysqlVersion,
84
    apacheVersion => $apacheVersion,
83
    apacheVersion => $apacheVersion,
85
    zebraVersion  => $zebraVersion,
84
    zebraVersion  => $zebraVersion,
86
    prefNoZebra   => $prefNoZebra,
87
    prefBiblioAddsAuthorities => $prefBiblioAddsAuthorities,
85
    prefBiblioAddsAuthorities => $prefBiblioAddsAuthorities,
88
    prefAutoCreateAuthorities => $prefAutoCreateAuthorities,
86
    prefAutoCreateAuthorities => $prefAutoCreateAuthorities,
89
    warnPrefBiblioAddsAuthorities => $warnPrefBiblioAddsAuthorities,
87
    warnPrefBiblioAddsAuthorities => $warnPrefBiblioAddsAuthorities,
(-)a/catalogue/search.pl (-12 / +4 lines)
Lines 517-534 my $facets; # this object stores the faceted results that display on the left-ha Link Here
517
my @results_array;
517
my @results_array;
518
my $results_hashref;
518
my $results_hashref;
519
519
520
if (C4::Context->preference('NoZebra')) {
520
eval {
521
    $query=~s/yr(:|=)\s*([\d]{1,4})-([\d]{1,4})/(yr>=$2 and yr<=$3)/g;
521
    ($error, $results_hashref, $facets) = getRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$itemtypes,$query_type,$scan);
522
    $simple_query=~s/yr\s*(:|=)([\d]{1,4})-([\d]{1,4})/(yr>=$2 and yr<=$3)/g;
522
};
523
    # warn $query; 
523
524
    eval {
525
        ($error, $results_hashref, $facets) = NZgetRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$query_type,$scan);
526
    };
527
} else {
528
    eval {
529
        ($error, $results_hashref, $facets) = getRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$itemtypes,$query_type,$scan);
530
    };
531
}
532
# This sorts the facets into alphabetical order
524
# This sorts the facets into alphabetical order
533
if ($facets) {
525
if ($facets) {
534
    foreach my $f (@$facets) {
526
    foreach my $f (@$facets) {
(-)a/installer/data/mysql/kohastructure.sql (-14 lines)
Lines 1378-1397 CREATE TABLE `notifys` ( Link Here
1378
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1378
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1379
1379
1380
--
1380
--
1381
-- Table structure for table `nozebra`
1382
--
1383
1384
DROP TABLE IF EXISTS `nozebra`;
1385
CREATE TABLE `nozebra` (
1386
  `server` varchar(20)     NOT NULL,
1387
  `indexname` varchar(40)  NOT NULL,
1388
  `value` varchar(250)     NOT NULL,
1389
  `biblionumbers` longtext NOT NULL,
1390
  KEY `indexname` (`server`,`indexname`),
1391
  KEY `value` (`server`,`value`))
1392
  ENGINE=InnoDB DEFAULT CHARSET=utf8;
1393
1394
--
1395
-- Table structure for table `oai_sets`
1381
-- Table structure for table `oai_sets`
1396
--
1382
--
1397
1383
(-)a/installer/data/mysql/ru-RU/mandatory/system_preferences_full_optimal_for_install_only.sql (-2 lines)
Lines 32-36 UPDATE systempreferences SET value = '1' WHERE variable = 'patronimages'; Link Here
32
32
33
UPDATE systempreferences SET value = '#200|<h2>Заглавие: |{200a}{. 200c}{ : 200e}{200d}{. 200h}{. 200i}|</h2>\r\n#500|<label class="ipt">Унифицированое заглавие: </label>|{500a}{. 500i}{. 500h}{. 500m}{. 500q}{. 500k}<br/>|\r\n#517|<label class="ipt"> </label>|{517a}{ : 517e}{. 517h}{, 517i}<br/>|\r\n#541|<label class="ipt"> </label>|{541a}{ : 541e}<br/>|\r\n#200||<label class="ipt">Автора: </label><br/>|\r\n#700||<a href="opac-search.pl?op=do_search&marclist=7009&operator==&type=intranet&value={7009}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по автору"></a>{700c}{ 700b}{ 700a}{ 700d}{ (700f)}{. 7004}<br/>|\r\n#701||<a href="opac-search.pl?op=do_search&marclist=7009&operator==&type=intranet&value={7019}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по автору"></a>{701c}{ 701b}{ 701a}{ 701d}{ (701f)}{. 7014}<br/>|\r\n#702||<a href="opac-search.pl?op=do_search&marclist=7009&operator==&type=intranet&value={7029}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по автору"></a>{702c}{ 702b}{ 702a}{ 702d}{ (702f)}{. 7024}<br/>|\r\n#710||<a href="opac-search.pl?op=do_search&marclist=7109&operator==&type=intranet&value={7109}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по автору"></a>{710a}{ (710c)}{. 710b}{ : 710d}{ ; 710f}{ ; 710e}<br/>|\r\n#711||<a href="opac-search.pl?op=do_search&marclist=7109&operator==&type=intranet&value={7119}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по автору"></a>{711a}{ (711c)}{. 711b}{ : 711d}{ ; 711f}{ ; 711e}<br/>|\r\n#712||<a href="opac-search.pl?op=do_search&marclist=7109&operator==&type=intranet&value={7129}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по автору"></a>{712a}{ (712c)}{. 712b}{ : 712d}{ ; 712f}{ ; 712e}<br/>|\r\n#210|<label class="ipt">Унифицированная форма заглавия: </label>|{ 210a}<br/>|\r\n#210|<label class="ipt">Издатель: </label>|{ 210c}<br/>|\r\n#210|<label class="ipt">Дата публикации: </label>|{ 210d}<br/>|\r\n#215|<label class="ipt">Физическое описание: </label>|{215a}{ : 215c}{ ; 215d}{ + 215e}|<br/>\r\n#225|<label class="ipt">Серія:</label>|<a href="opac-search.pl?op=do_search&marclist=225a&operator==&type=intranet&value={225a}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {225a}"></a>{ (225a}{ = 225d}{ : 225e}{. 225h}{. 225i}{ / 225f}{, 225x}{ ; 225v}|)<br/>\r\n#200||<label class="ipt">Тематические рубрики: </label><br/>|\r\n#600||<a href="opac-search.pl?op=do_search&marclist=6009&operator==&type=intranet&value={6009}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {6009}"></a>{ 600c}{ 600b}{ 600a}{ 600d}{ (600f)} {-- 600x }{-- 600z }{-- 600y}<br />|\r\n#604||<a href="opac-search.pl?op=do_search&marclist=6049&operator==&type=intranet&value={6049}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {6049}"></a>{ 604a}{. 604t}<br />|\r\n#601||<a href="opac-search.pl?op=do_search&marclist=6019&operator==&type=intranet&value={6019}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {6019}"></a>{ 601a}{ (601c)}{. 601b}{ : 601d} { ; 601f}{ ; 601e}{ -- 601x }{-- 601z }{-- 601y}<br />|\r\n#605||<a href="opac-search.pl?op=do_search&marclist=6059&operator==&type=intranet&value={6059}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {6059}"></a>{ 605a}{. 605i}{. 605h}{. 605k}{. 605m}{. 605q} {-- 605x }{-- 605z }{-- 605y }{-- 605l}<br />|\r\n#606||<a href="opac-search.pl?op=do_search&marclist=6069&operator==&type=intranet&value={6069}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {6069}">xx</a>{ 606a}{-- 606x }{-- 606z }{606y }<br />|\r\n#607||<a href="opac-search.pl?op=do_search&marclist=6079&operator==&type=intranet&value={6079}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {6079}"></a>{ 607a}{-- 607x}{-- 607z}{-- 607y}<br />|\r\n#010|<label class="ipt">ISBN: </label>|{010a}|<br/>\r\n#011|<label class="ipt">ISSN: </label>|{011a}|<br/>\r\n#200||<label class="ipt">Заметки: </label>|<br/>\r\n#300||{300a}|<br/>\r\n#320||{320a}|<br/>\r\n#327||{327a}|<br/>\r\n#328||{328a}|<br/>\r\n#200||<br/><h2>Экземпляры</h2>|\r\n#200|<table>|<th>Расположение</th><th>Cote</th>|\r\n#995||<tr><td>{995e}&nbsp;&nbsp;</td><td> {995k}</td></tr>|\r\n#200|||</table>' WHERE variable = 'ISBD';
33
UPDATE systempreferences SET value = '#200|<h2>Заглавие: |{200a}{. 200c}{ : 200e}{200d}{. 200h}{. 200i}|</h2>\r\n#500|<label class="ipt">Унифицированое заглавие: </label>|{500a}{. 500i}{. 500h}{. 500m}{. 500q}{. 500k}<br/>|\r\n#517|<label class="ipt"> </label>|{517a}{ : 517e}{. 517h}{, 517i}<br/>|\r\n#541|<label class="ipt"> </label>|{541a}{ : 541e}<br/>|\r\n#200||<label class="ipt">Автора: </label><br/>|\r\n#700||<a href="opac-search.pl?op=do_search&marclist=7009&operator==&type=intranet&value={7009}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по автору"></a>{700c}{ 700b}{ 700a}{ 700d}{ (700f)}{. 7004}<br/>|\r\n#701||<a href="opac-search.pl?op=do_search&marclist=7009&operator==&type=intranet&value={7019}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по автору"></a>{701c}{ 701b}{ 701a}{ 701d}{ (701f)}{. 7014}<br/>|\r\n#702||<a href="opac-search.pl?op=do_search&marclist=7009&operator==&type=intranet&value={7029}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по автору"></a>{702c}{ 702b}{ 702a}{ 702d}{ (702f)}{. 7024}<br/>|\r\n#710||<a href="opac-search.pl?op=do_search&marclist=7109&operator==&type=intranet&value={7109}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по автору"></a>{710a}{ (710c)}{. 710b}{ : 710d}{ ; 710f}{ ; 710e}<br/>|\r\n#711||<a href="opac-search.pl?op=do_search&marclist=7109&operator==&type=intranet&value={7119}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по автору"></a>{711a}{ (711c)}{. 711b}{ : 711d}{ ; 711f}{ ; 711e}<br/>|\r\n#712||<a href="opac-search.pl?op=do_search&marclist=7109&operator==&type=intranet&value={7129}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по автору"></a>{712a}{ (712c)}{. 712b}{ : 712d}{ ; 712f}{ ; 712e}<br/>|\r\n#210|<label class="ipt">Унифицированная форма заглавия: </label>|{ 210a}<br/>|\r\n#210|<label class="ipt">Издатель: </label>|{ 210c}<br/>|\r\n#210|<label class="ipt">Дата публикации: </label>|{ 210d}<br/>|\r\n#215|<label class="ipt">Физическое описание: </label>|{215a}{ : 215c}{ ; 215d}{ + 215e}|<br/>\r\n#225|<label class="ipt">Серія:</label>|<a href="opac-search.pl?op=do_search&marclist=225a&operator==&type=intranet&value={225a}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {225a}"></a>{ (225a}{ = 225d}{ : 225e}{. 225h}{. 225i}{ / 225f}{, 225x}{ ; 225v}|)<br/>\r\n#200||<label class="ipt">Тематические рубрики: </label><br/>|\r\n#600||<a href="opac-search.pl?op=do_search&marclist=6009&operator==&type=intranet&value={6009}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {6009}"></a>{ 600c}{ 600b}{ 600a}{ 600d}{ (600f)} {-- 600x }{-- 600z }{-- 600y}<br />|\r\n#604||<a href="opac-search.pl?op=do_search&marclist=6049&operator==&type=intranet&value={6049}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {6049}"></a>{ 604a}{. 604t}<br />|\r\n#601||<a href="opac-search.pl?op=do_search&marclist=6019&operator==&type=intranet&value={6019}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {6019}"></a>{ 601a}{ (601c)}{. 601b}{ : 601d} { ; 601f}{ ; 601e}{ -- 601x }{-- 601z }{-- 601y}<br />|\r\n#605||<a href="opac-search.pl?op=do_search&marclist=6059&operator==&type=intranet&value={6059}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {6059}"></a>{ 605a}{. 605i}{. 605h}{. 605k}{. 605m}{. 605q} {-- 605x }{-- 605z }{-- 605y }{-- 605l}<br />|\r\n#606||<a href="opac-search.pl?op=do_search&marclist=6069&operator==&type=intranet&value={6069}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {6069}">xx</a>{ 606a}{-- 606x }{-- 606z }{606y }<br />|\r\n#607||<a href="opac-search.pl?op=do_search&marclist=6079&operator==&type=intranet&value={6079}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Поиск по {6079}"></a>{ 607a}{-- 607x}{-- 607z}{-- 607y}<br />|\r\n#010|<label class="ipt">ISBN: </label>|{010a}|<br/>\r\n#011|<label class="ipt">ISSN: </label>|{011a}|<br/>\r\n#200||<label class="ipt">Заметки: </label>|<br/>\r\n#300||{300a}|<br/>\r\n#320||{320a}|<br/>\r\n#327||{327a}|<br/>\r\n#328||{328a}|<br/>\r\n#200||<br/><h2>Экземпляры</h2>|\r\n#200|<table>|<th>Расположение</th><th>Cote</th>|\r\n#995||<tr><td>{995e}&nbsp;&nbsp;</td><td> {995k}</td></tr>|\r\n#200|||</table>' WHERE variable = 'ISBD';
34
34
35
UPDATE systempreferences SET value = '\'title\' =>\r\n\'200a,200c,200d,200e,225a,225d,225e,225f,225h,225i,225v,500*,501*,503*,510*,\r\n512*,513*,514*,515*,516*,517*,518*,519*,520*,530*,531*,532*,540*,541*,545*,6\r\n04t,610t,605a\',\r\n\'author\'=>\'200f,600a,601a,604a,700a,700b,700c,700d,700a,701b,701c,701d,702a,\r\n702b,702c,702d,710a,710b,710c,710d,711a,711b,711c,711d,712a,712b,712c,712d\',\r\n\'se\'=>\'225a\',\r\n        \'isbn\' => \'010a\',\r\n        \'issn\' => \'011a\',\r\n        \'biblionumber\' =>\'0909\',\r\n        \'itemtype\' => \'200b\',\r\n        \'language\' => \'101a\',\r\n        \'pl\' => \'210a\',\r\n        \'publisher\' => \'210c\',\r\n        \'date\' => \'210d\',\r\n        \'note\' =>\r\n\'300a,301a,302a,303a,304a,305a,306az,307a,308a,309a,310a,311a,312a,313a,314a\r\n,315a,316a,317a,318a,319a,320a,321a,322a,323a,324a,325a,326a,327a,328a,330a,\r\n332a,333a,336a,337a,345a\',\r\n        \'an\' => \'6009,6019,6069,6109,6079\',\r\n        \'su\' => \'600a,601a,606a,610a,607a,608a\',\r\n\'lcn\'=>\'686a,995k\',\r\n\'yr\'=>\'210d\',\r\n        \'mt\' => \'200b\',\r\n        \'dewey\' => \'676a\',\r\n        \'host-item\' => \'995b,995c\',\'keyword\' => \'200*,600*,700*,400*,210*\' ' WHERE variable = 'NoZebraIndexes';
36
(-)a/installer/data/mysql/ru-RU/mandatory/system_preferences_optimal_values_insert_only.sql (-2 lines)
Lines 47-54 UPDATE systempreferences SET value='942hv' WHERE variable='itemcallnumber'; Link Here
47
47
48
UPDATE systempreferences SET value='UNIMARC' WHERE variable='marcflavour';
48
UPDATE systempreferences SET value='UNIMARC' WHERE variable='marcflavour';
49
49
50
UPDATE systempreferences SET value='\'title\' =>\r\n\'200a,200c,200d,200e,225a,225d,225e,225f,225h,225i,225v,500*,501*,503*,510*,\r\n512*,513*,514*,515*,516*,517*,518*,519*,520*,530*,531*,532*,540*,541*,545*,6\r\n04t,610t,605a\',\r\n\'author\'=>\'200f,600a,601a,604a,700a,700b,700c,700d,700a,701b,701c,701d,702a,\r\n702b,702c,702d,710a,710b,710c,710d,711a,711b,711c,711d,712a,712b,712c,712d\',\r\n\'se\'=>\'225a\',\r\n        \'isbn\' => \'010a\',\r\n        \'issn\' => \'011a\',\r\n        \'biblionumber\' =>\'0909\',\r\n        \'itemtype\' => \'200b\',\r\n        \'language\' => \'101a\',\r\n        \'pl\' => \'210a\',\r\n        \'publisher\' => \'210c\',\r\n        \'date\' => \'210d\',\r\n        \'note\' =>\r\n\'300a,301a,302a,303a,304a,305a,306az,307a,308a,309a,310a,311a,312a,313a,314a\r\n,315a,316a,317a,318a,319a,320a,321a,322a,323a,324a,325a,326a,327a,328a,330a,\r\n332a,333a,336a,337a,345a\',\r\n        \'an\' => \'6009,6019,6069,6109,6079\',\r\n        \'su\' => \'600a,601a,606a,610a,607a,608a\',\r\n\'lcn\'=>\'686a,995k\',\r\n\'yr\'=>\'210d\',\r\n        \'mt\' => \'200b\',\r\n        \'dewey\' => \'676a\',\r\n        \'host-item\' => \'995b,995c\',\'keyword\' => \'200*,600*,700*,400*,210*\' ' WHERE variable='NoZebraIndexes';
51
52
-- Circulation - Оборот
50
-- Circulation - Оборот
53
51
54
-- I18N/L10N
52
-- I18N/L10N
(-)a/installer/data/mysql/sysprefs.sql (-3 lines)
Lines 115-121 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES Link Here
115
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('z3950NormalizeAuthor',0,'If ON, Personal Name Authorities will replace authors in biblio.author','','YesNo');
115
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('z3950NormalizeAuthor',0,'If ON, Personal Name Authorities will replace authors in biblio.author','','YesNo');
116
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ReservesNeedReturns',1,'If ON, a hold placed on an item available in this library must be checked-in, otherwise, a hold on a specific item, that is in the library & available is considered available','','YesNo');
116
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('ReservesNeedReturns',1,'If ON, a hold placed on an item available in this library must be checked-in, otherwise, a hold on a specific item, that is in the library & available is considered available','','YesNo');
117
INSERT INTO `systempreferences` (variable,value,explanation,options,type)  VALUES ('DebugLevel',2,'Define the level of debugging information sent to the browser when errors are encountered (set to 0 in production). 0=none, 1=some, 2=most','0|1|2','Choice');
117
INSERT INTO `systempreferences` (variable,value,explanation,options,type)  VALUES ('DebugLevel',2,'Define the level of debugging information sent to the browser when errors are encountered (set to 0 in production). 0=none, 1=some, 2=most','0|1|2','Choice');
118
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('NoZebra',0,'If ON, Zebra indexing is turned off, simpler setup, but slower searches. WARNING: using NoZebra on even modest sized collections is very slow.','','YesNo');
119
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('SessionStorage','mysql','Use database or a temporary file for storing session data','mysql|Pg|tmp','Choice');
118
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('SessionStorage','mysql','Use database or a temporary file for storing session data','mysql|Pg|tmp','Choice');
120
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('CircAutocompl',1,'If ON, autocompletion is enabled for the Circulation input',NULL,'YesNo');
119
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('CircAutocompl',1,'If ON, autocompletion is enabled for the Circulation input',NULL,'YesNo');
121
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('RoutingSerials',1,'If ON, serials routing is enabled',NULL,'YesNo');
120
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('RoutingSerials',1,'If ON, serials routing is enabled',NULL,'YesNo');
Lines 174-181 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES Link Here
174
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OPACBaseURL',NULL,'Specify the Base URL of the OPAC, e.g., opac.mylibrary.com, the http:// will be added automatically by Koha.',NULL,'Free');
173
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OPACBaseURL',NULL,'Specify the Base URL of the OPAC, e.g., opac.mylibrary.com, the http:// will be added automatically by Koha.',NULL,'Free');
175
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('language','en','Set the default language in the staff client.',NULL,'Languages');
174
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('language','en','Set the default language in the staff client.',NULL,'Languages');
176
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('QueryAutoTruncate',1,'If ON, query truncation is enabled by default',NULL,'YesNo');
175
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('QueryAutoTruncate',1,'If ON, query truncation is enabled by default',NULL,'YesNo');
177
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('QueryRemoveStopwords',0,'If ON, stopwords listed in the Administration area will be removed from queries',NULL,'YesNo');
178
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('NoZebraIndexes','\'title\' => \'130a,210a,222a,240a,243a,245a,245b,246a,246b,247a,247b,250a,250b,440a,830a\',\r\n\'author\' => \'100a,100b,100c,100d,110a,111a,111b,111c,111d,245c,700a,710a,711a,800a,810a,811a\',\r\n\'isbn\' => \'020a\',\r\n\'issn\' => \'022a\',\r\n\'lccn\' => \'010a\',\r\n\'biblionumber\' => \'999c\',\r\n\'itemtype\' => \'942c\',\r\n\'publisher\' => \'260b\',\r\n\'date\' => \'260c\',\r\n\'note\' => \'500a, 501a,504a,505a,508a,511a,518a,520a,521a,522a,524a,526a,530a,533a,538a,541a,546a,555a,556a,562a,563a,583a,585a,582a\',\r\n\'subject\' => \'600*,610*,611*,630*,650*,651*,653*,654*,655*,662*,690*\',\r\n\'dewey\' => \'082\',\r\n\'bc\' => \'952p\',\r\n\'callnum\' => \'952o\',\r\n\'an\' => \'6009,6109,6119\',\r\n\'homebranch\' => \'952a,952c\'','Enter a specific hash for NoZebra indexes. Enter : \'indexname\' => \'100a,245a,500*\',\'index2\' => \'...\'','70|10','Textarea');
179
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OpacRenewalAllowed',0,'If ON, users can renew their issues directly from their OPAC account',NULL,'YesNo');
176
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OpacRenewalAllowed',0,'If ON, users can renew their issues directly from their OPAC account',NULL,'YesNo');
180
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('PatronsPerPage','20','Number of Patrons Per Page displayed by default','20','Integer');
177
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('PatronsPerPage','20','Number of Patrons Per Page displayed by default','20','Integer');
181
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('HomeOrHoldingBranch','holdingbranch','Used by Circulation to determine which branch of an item to check with independent branches on, and by search to determine which branch to choose for availability ','holdingbranch|homebranch','Choice');
178
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('HomeOrHoldingBranch','holdingbranch','Used by Circulation to determine which branch of an item to check with independent branches on, and by search to determine which branch to choose for availability ','holdingbranch|homebranch','Choice');
(-)a/installer/data/mysql/uk-UA/mandatory/system_preferences_full_optimal_for_install_only.sql (-28 lines)
Lines 31-61 UPDATE systempreferences SET value = 'Тут будуть важливі пос Link Here
31
UPDATE systempreferences SET value = '1' WHERE variable = 'patronimages';
31
UPDATE systempreferences SET value = '1' WHERE variable = 'patronimages';
32
32
33
UPDATE systempreferences SET value = '#200|<h2>Заголовок: |{200a}{. 200c}{ : 200e}{200d}{. 200h}{. 200i}|</h2>\r\n#500|<label class="ipt">Уніфікована назва: </label>|{500a}{. 500i}{. 500h}{. 500m}{. 500q}{. 500k}<br/>|\r\n#517|<label class="ipt"> </label>|{517a}{ : 517e}{. 517h}{, 517i}<br/>|\r\n#541|<label class="ipt"> </label>|{541a}{ : 541e}<br/>|\r\n#200||<label class="ipt">Автори: </label><br/>|\r\n#700||<a href="opac-search.pl?op=do_search&marclist=7009&operator==&type=intranet&value={7009}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за автором"></a>{700c}{ 700b}{ 700a}{ 700d}{ (700f)}{. 7004}<br/>|\r\n#701||<a href="opac-search.pl?op=do_search&marclist=7009&operator==&type=intranet&value={7019}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за автором"></a>{701c}{ 701b}{ 701a}{ 701d}{ (701f)}{. 7014}<br/>|\r\n#702||<a href="opac-search.pl?op=do_search&marclist=7009&operator==&type=intranet&value={7029}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за автором"></a>{702c}{ 702b}{ 702a}{ 702d}{ (702f)}{. 7024}<br/>|\r\n#710||<a href="opac-search.pl?op=do_search&marclist=7109&operator==&type=intranet&value={7109}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за автором"></a>{710a}{ (710c)}{. 710b}{ : 710d}{ ; 710f}{ ; 710e}<br/>|\r\n#711||<a href="opac-search.pl?op=do_search&marclist=7109&operator==&type=intranet&value={7119}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за автором"></a>{711a}{ (711c)}{. 711b}{ : 711d}{ ; 711f}{ ; 711e}<br/>|\r\n#712||<a href="opac-search.pl?op=do_search&marclist=7109&operator==&type=intranet&value={7129}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за автором"></a>{712a}{ (712c)}{. 712b}{ : 712d}{ ; 712f}{ ; 712e}<br/>|\r\n#210|<label class="ipt">Уніфікована форма назви: </label>|{ 210a}<br/>|\r\n#210|<label class="ipt">Видавець: </label>|{ 210c}<br/>|\r\n#210|<label class="ipt">Дата публікації: </label>|{ 210d}<br/>|\r\n#215|<label class="ipt">Фізичний опис: </label>|{215a}{ : 215c}{ ; 215d}{ + 215e}|<br/>\r\n#225|<label class="ipt">Серія:</label>|<a href="opac-search.pl?op=do_search&marclist=225a&operator==&type=intranet&value={225a}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {225a}"></a>{ (225a}{ = 225d}{ : 225e}{. 225h}{. 225i}{ / 225f}{, 225x}{ ; 225v}|)<br/>\r\n#200||<label class="ipt">Предметні рубрики: </label><br/>|\r\n#600||<a href="opac-search.pl?op=do_search&marclist=6009&operator==&type=intranet&value={6009}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {6009}"></a>{ 600c}{ 600b}{ 600a}{ 600d}{ (600f)} {-- 600x }{-- 600z }{-- 600y}<br />|\r\n#604||<a href="opac-search.pl?op=do_search&marclist=6049&operator==&type=intranet&value={6049}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {6049}"></a>{ 604a}{. 604t}<br />|\r\n#601||<a href="opac-search.pl?op=do_search&marclist=6019&operator==&type=intranet&value={6019}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {6019}"></a>{ 601a}{ (601c)}{. 601b}{ : 601d} { ; 601f}{ ; 601e}{ -- 601x }{-- 601z }{-- 601y}<br />|\r\n#605||<a href="opac-search.pl?op=do_search&marclist=6059&operator==&type=intranet&value={6059}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {6059}"></a>{ 605a}{. 605i}{. 605h}{. 605k}{. 605m}{. 605q} {-- 605x }{-- 605z }{-- 605y }{-- 605l}<br />|\r\n#606||<a href="opac-search.pl?op=do_search&marclist=6069&operator==&type=intranet&value={6069}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {6069}">xx</a>{ 606a}{-- 606x }{-- 606z }{606y }<br />|\r\n#607||<a href="opac-search.pl?op=do_search&marclist=6079&operator==&type=intranet&value={6079}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {6079}"></a>{ 607a}{-- 607x}{-- 607z}{-- 607y}<br />|\r\n#010|<label class="ipt">ISBN: </label>|{010a}|<br/>\r\n#011|<label class="ipt">ISSN: </label>|{011a}|<br/>\r\n#200||<label class="ipt">Нотатки: </label>|<br/>\r\n#300||{300a}|<br/>\r\n#320||{320a}|<br/>\r\n#327||{327a}|<br/>\r\n#328||{328a}|<br/>\r\n#200||<br/><h2>Примірники</h2>|\r\n#200|<table>|<th>Місцезнаходження</th><th>Cote</th>|\r\n#995||<tr><td>{995e}&nbsp;&nbsp;</td><td> {995k}</td></tr>|\r\n#200|||</table>' WHERE variable = 'ISBD';
33
UPDATE systempreferences SET value = '#200|<h2>Заголовок: |{200a}{. 200c}{ : 200e}{200d}{. 200h}{. 200i}|</h2>\r\n#500|<label class="ipt">Уніфікована назва: </label>|{500a}{. 500i}{. 500h}{. 500m}{. 500q}{. 500k}<br/>|\r\n#517|<label class="ipt"> </label>|{517a}{ : 517e}{. 517h}{, 517i}<br/>|\r\n#541|<label class="ipt"> </label>|{541a}{ : 541e}<br/>|\r\n#200||<label class="ipt">Автори: </label><br/>|\r\n#700||<a href="opac-search.pl?op=do_search&marclist=7009&operator==&type=intranet&value={7009}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за автором"></a>{700c}{ 700b}{ 700a}{ 700d}{ (700f)}{. 7004}<br/>|\r\n#701||<a href="opac-search.pl?op=do_search&marclist=7009&operator==&type=intranet&value={7019}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за автором"></a>{701c}{ 701b}{ 701a}{ 701d}{ (701f)}{. 7014}<br/>|\r\n#702||<a href="opac-search.pl?op=do_search&marclist=7009&operator==&type=intranet&value={7029}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за автором"></a>{702c}{ 702b}{ 702a}{ 702d}{ (702f)}{. 7024}<br/>|\r\n#710||<a href="opac-search.pl?op=do_search&marclist=7109&operator==&type=intranet&value={7109}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за автором"></a>{710a}{ (710c)}{. 710b}{ : 710d}{ ; 710f}{ ; 710e}<br/>|\r\n#711||<a href="opac-search.pl?op=do_search&marclist=7109&operator==&type=intranet&value={7119}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за автором"></a>{711a}{ (711c)}{. 711b}{ : 711d}{ ; 711f}{ ; 711e}<br/>|\r\n#712||<a href="opac-search.pl?op=do_search&marclist=7109&operator==&type=intranet&value={7129}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за автором"></a>{712a}{ (712c)}{. 712b}{ : 712d}{ ; 712f}{ ; 712e}<br/>|\r\n#210|<label class="ipt">Уніфікована форма назви: </label>|{ 210a}<br/>|\r\n#210|<label class="ipt">Видавець: </label>|{ 210c}<br/>|\r\n#210|<label class="ipt">Дата публікації: </label>|{ 210d}<br/>|\r\n#215|<label class="ipt">Фізичний опис: </label>|{215a}{ : 215c}{ ; 215d}{ + 215e}|<br/>\r\n#225|<label class="ipt">Серія:</label>|<a href="opac-search.pl?op=do_search&marclist=225a&operator==&type=intranet&value={225a}"> <img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {225a}"></a>{ (225a}{ = 225d}{ : 225e}{. 225h}{. 225i}{ / 225f}{, 225x}{ ; 225v}|)<br/>\r\n#200||<label class="ipt">Предметні рубрики: </label><br/>|\r\n#600||<a href="opac-search.pl?op=do_search&marclist=6009&operator==&type=intranet&value={6009}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {6009}"></a>{ 600c}{ 600b}{ 600a}{ 600d}{ (600f)} {-- 600x }{-- 600z }{-- 600y}<br />|\r\n#604||<a href="opac-search.pl?op=do_search&marclist=6049&operator==&type=intranet&value={6049}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {6049}"></a>{ 604a}{. 604t}<br />|\r\n#601||<a href="opac-search.pl?op=do_search&marclist=6019&operator==&type=intranet&value={6019}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {6019}"></a>{ 601a}{ (601c)}{. 601b}{ : 601d} { ; 601f}{ ; 601e}{ -- 601x }{-- 601z }{-- 601y}<br />|\r\n#605||<a href="opac-search.pl?op=do_search&marclist=6059&operator==&type=intranet&value={6059}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {6059}"></a>{ 605a}{. 605i}{. 605h}{. 605k}{. 605m}{. 605q} {-- 605x }{-- 605z }{-- 605y }{-- 605l}<br />|\r\n#606||<a href="opac-search.pl?op=do_search&marclist=6069&operator==&type=intranet&value={6069}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {6069}">xx</a>{ 606a}{-- 606x }{-- 606z }{606y }<br />|\r\n#607||<a href="opac-search.pl?op=do_search&marclist=6079&operator==&type=intranet&value={6079}"><img border="0" src="/opac-tmpl/css/en/images/filefind.png" height="15" title="Пошук за {6079}"></a>{ 607a}{-- 607x}{-- 607z}{-- 607y}<br />|\r\n#010|<label class="ipt">ISBN: </label>|{010a}|<br/>\r\n#011|<label class="ipt">ISSN: </label>|{011a}|<br/>\r\n#200||<label class="ipt">Нотатки: </label>|<br/>\r\n#300||{300a}|<br/>\r\n#320||{320a}|<br/>\r\n#327||{327a}|<br/>\r\n#328||{328a}|<br/>\r\n#200||<br/><h2>Примірники</h2>|\r\n#200|<table>|<th>Місцезнаходження</th><th>Cote</th>|\r\n#995||<tr><td>{995e}&nbsp;&nbsp;</td><td> {995k}</td></tr>|\r\n#200|||</table>' WHERE variable = 'ISBD';
34
35
UPDATE systempreferences SET value = "
36
        'title' => '200a,200c,200d,200e,225a,225d,225e,225f,225h,225i,225v,500*,501*,503*,510*,512*,513*,514*,515*,516*,517*,518*,519*,520*,530*,531*,532*,540*,541*,545*,604t,610t,605a',
37
        'author' => '200f,600a,601a,604a,700a,700b,700c,700d,700a,701b,701c,701d,702a,702b,702c,702d,710a,710b,710c,710d,711a,711b,711c,711d,712a,712b,712c,712d',
38
        'se' => '225a',
39
        'isbn' => '010a',
40
        'issn' => '011a',
41
        'biblionumber' => '9999',
42
        'itemtype' => '200b,942c,952y',
43
        'language' => '101a',
44
        'pl' => '210a',
45
        'publisher' => '210c',
46
        'date' => '210d',
47
        'note' => '300a,301a,302a,303a,304a,305a,306az,307a,308a,309a,310a,311a,312a,313a,314a,315a,316a,317a,318a,319a,320a,321a,322a,323a,324a,325a,326a,327a,328a,330a,332a,333a,336a,337a,345a',
48
        'Koha-Auth-Number' => '6009,6019,6029,6039,6049,6059,6069,6109,7009,7019,7029,7109,7119,7129',
49
        'subject' => '600*,601*,606*,610*',
50
        'an' => '6009,6019,6069,6109,6079',
51
        'su' => '600a,601a,606a,610a,607a,608a',
52
        'lcn' => '686a,952o',
53
        'yr' => '210d',
54
        'mt' => '200b',
55
        'dewey' => '676a',
56
        'bc' => '952p',
57
        'callnum' => '952o',
58
        'homebranch' => '952a,952c',
59
        'host-item' => '992b,992c',
60
        'keyword' => '200*,600*,700*,400*,210*' 
61
" WHERE variable = 'NoZebraIndexes';
(-)a/installer/data/mysql/uk-UA/mandatory/system_preferences_optimal_values_insert_only.sql (-28 lines)
Lines 47-80 UPDATE systempreferences SET value='942hv' WHERE variable='itemcallnumber'; Link Here
47
47
48
UPDATE systempreferences SET value='UNIMARC' WHERE variable='marcflavour';
48
UPDATE systempreferences SET value='UNIMARC' WHERE variable='marcflavour';
49
49
50
UPDATE systempreferences SET value="
51
        'title' => '200a,200c,200d,200e,225a,225d,225e,225f,225h,225i,225v,500*,501*,503*,510*,512*,513*,514*,515*,516*,517*,518*,519*,520*,530*,531*,532*,540*,541*,545*,604t,610t,605a',
52
        'author' => '200f,600a,601a,604a,700a,700b,700c,700d,700a,701b,701c,701d,702a,702b,702c,702d,710a,710b,710c,710d,711a,711b,711c,711d,712a,712b,712c,712d',
53
        'se' => '225a',
54
        'isbn' => '010a',
55
        'issn' => '011a',
56
        'biblionumber' => '9999',
57
        'itemtype' => '200b,942c,952y',
58
        'language' => '101a',
59
        'pl' => '210a',
60
        'publisher' => '210c',
61
        'date' => '210d',
62
        'note' => '300a,301a,302a,303a,304a,305a,306az,307a,308a,309a,310a,311a,312a,313a,314a,315a,316a,317a,318a,319a,320a,321a,322a,323a,324a,325a,326a,327a,328a,330a,332a,333a,336a,337a,345a',
63
        'Koha-Auth-Number' => '6009,6019,6029,6039,6049,6059,6069,6109,7009,7019,7029,7109,7119,7129',
64
        'subject' => '600*,601*,606*,610*',
65
        'an' => '6009,6019,6069,6109,6079',
66
        'su' => '600a,601a,606a,610a,607a,608a',
67
        'lcn' => '686a,952o',
68
        'yr' => '210d',
69
        'mt' => '200b',
70
        'dewey' => '676a',
71
        'bc' => '952p',
72
        'callnum' => '952o',
73
        'homebranch' => '952a,952c',
74
        'host-item' => '992b,992c',
75
        'keyword' => '200*,600*,700*,400*,210*' 
76
" WHERE variable='NoZebraIndexes';
77
78
-- Circulation - Обіг
50
-- Circulation - Обіг
79
51
80
-- I18N/L10N
52
-- I18N/L10N
(-)a/installer/install.pl (-1 lines)
Lines 189-195 elsif ( $step && $step == 3 ) { Link Here
189
    }
189
    }
190
    elsif ( $op && $op eq 'finish' ) {
190
    elsif ( $op && $op eq 'finish' ) {
191
        $installer->set_version_syspref();
191
        $installer->set_version_syspref();
192
        $installer->set_indexing_engine(0); # use Zebra
193
192
194
        # Installation is finished.
193
        # Installation is finished.
195
        # We just deny anybody access to install
194
        # We just deny anybody access to install
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/admin-menu.inc (-1 lines)
Lines 60-66 Link Here
60
<h5>Additional parameters</h5>
60
<h5>Additional parameters</h5>
61
61
62
<ul>
62
<ul>
63
    [% IF ( NoZebra ) %]<li><a href="/cgi-bin/koha/admin/stopwords.pl">Stop words</a></li>[% END %]
64
	<!-- <li><a href="/cgi-bin/koha/admin/printers.pl">Network Printers</a></li> -->
63
	<!-- <li><a href="/cgi-bin/koha/admin/printers.pl">Network Printers</a></li> -->
65
    <li><a href="/cgi-bin/koha/admin/z3950servers.pl">Z39.50 client targets</a></li>
64
    <li><a href="/cgi-bin/koha/admin/z3950servers.pl">Z39.50 client targets</a></li>
66
    <li><a href="/cgi-bin/koha/admin/didyoumean.pl">Did you mean?</a></li>
65
    <li><a href="/cgi-bin/koha/admin/didyoumean.pl">Did you mean?</a></li>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt (-4 / +1 lines)
Lines 104-115 Link Here
104
            <p>Please log in instead with a regular staff account. To create a staff account, create a library, a patron category 'Staff' and add a new patron. Then give this patron permissions from 'More' in the toolbar.</p>
104
            <p>Please log in instead with a regular staff account. To create a staff account, create a library, a patron category 'Staff' and add a new patron. Then give this patron permissions from 'More' in the toolbar.</p>
105
        [% END %]
105
        [% END %]
106
            <h2>Warnings regarding the system configuration</h2>
106
            <h2>Warnings regarding the system configuration</h2>
107
        [% IF ( (prefNoZebra) || (warnPrefBiblioAddsAuthorities) || warnPrefEasyAnalyticalRecords ) %]
107
        [% IF ( (warnPrefBiblioAddsAuthorities) || warnPrefEasyAnalyticalRecords ) %]
108
        <table>
108
        <table>
109
            <caption>Preferences</caption>
109
            <caption>Preferences</caption>
110
            [% IF (prefNoZebra) %]
111
            <tr><th scope="row"><b>Warning</b> </th><td>System preference 'nozebra' set. Deprectated!</td></tr>
112
            [% END %]
113
            [% IF (warnPrefBiblioAddsAuthorities) %]
110
            [% IF (warnPrefBiblioAddsAuthorities) %]
114
            <tr><th scope="row"><b>Warning</b> </th><td>System preference 'AutoCreateAuthorities' set, but needs 'BiblioAddsAuthorities' set as well.</td></tr>
111
            <tr><th scope="row"><b>Warning</b> </th><td>System preference 'AutoCreateAuthorities' set, but needs 'BiblioAddsAuthorities' set as well.</td></tr>
115
            [% END %]
112
            [% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/admin-home.tt (-2 lines)
Lines 101-108 Link Here
101
101
102
<h3>Additional parameters</h3>
102
<h3>Additional parameters</h3>
103
<dl>
103
<dl>
104
	[% IF ( NoZebra ) %]<dt><a href="/cgi-bin/koha/admin/stopwords.pl">Stop words</a></dt>
105
	<dd>Words ignored during search.</dd>[% END %]
106
	<!-- <dt><a href="/cgi-bin/koha/admin/printers.pl">Network Printers</a></dt>
104
	<!-- <dt><a href="/cgi-bin/koha/admin/printers.pl">Network Printers</a></dt>
107
	<dd>Printers (UNIX paths).</dd> -->
105
	<dd>Printers (UNIX paths).</dd> -->
108
    <dt><a href="/cgi-bin/koha/admin/z3950servers.pl">Z39.50 client targets</a></dt>
106
    <dt><a href="/cgi-bin/koha/admin/z3950servers.pl">Z39.50 client targets</a></dt>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt (-40 lines)
Lines 391-436 YAHOO.util.Event.onContentReady("searchheader", function () { Link Here
391
            </form>
391
            </form>
392
        [% ELSE %]
392
        [% ELSE %]
393
393
394
                [% IF ( NoZebra ) %]
395
                <!-- ######### -->
396
                <div id="facets">
397
                <dl>
398
                <!-- FACETS START -->
399
                [% IF ( opacfacets ) %]
400
                    <dt id="facets1" onclick="var Elt=document.getElementById('facets_list');if (Elt.style.display!='block'){Elt.style.display='block';} else {Elt.style.display='none';}">
401
                    Refine your search
402
                    </dt>
403
                    <dd id="facets_list" style="display:none;">
404
                    <ul>
405
                    [% FOREACH facets_loo IN facets_loop %]
406
                    <li id="[% facets_loo.type_id %]">[% facets_loo.type_label %]
407
                        <ul>
408
                        [% FOREACH facet IN facets_loo.facets %]
409
                            <li>
410
                                <a href="/cgi-bin/koha/catalogue/search.pl?q=[% facet.searchdesc %] and [% facet.type_link_value %]:[% facet.facet_link_value %]" title="[% facet.facet_title_value %]">
411
                                    [% facet.facet_label_value %]
412
                                </a> ([% facet.facet_count %])
413
                            </li>
414
                        [% END %]
415
                        [% IF ( facets_loo.expandable ) %]
416
                            <li class="showmore">
417
                                <a href="/cgi-bin/koha/catalogue/search.pl?q=[% facets_loo.searchdesc %][% IF ( offset ) %]&amp;offset=[% offset %][% END %]&amp;expand=[% facets_loo.expand %]#[% facets_loo.type_id %]">
418
                                    Show more
419
                                </a>
420
                            </li>
421
                        [% END %]
422
                        </ul>
423
                    </li>
424
                    [% END %]
425
                    </ul>
426
                    </dd>
427
                [% END %]
428
                <!-- FACETS END -->
429
                </dl>
430
            </div>
431
            <!-- ######### -->
432
            <!-- NoZebra -->[% END %]
433
434
            <div id="searchresults">
394
            <div id="searchresults">
435
                <form action="/cgi-bin/koha/catalogue/search.pl" method="get" name="bookbag_form" id="bookbag_form">
395
                <form action="/cgi-bin/koha/catalogue/search.pl" method="get" name="bookbag_form" id="bookbag_form">
436
                [% IF ( searchdesc ) %]
396
                [% IF ( searchdesc ) %]
(-)a/misc/migration_tools/rebuild_nozebra.pl (-343 lines)
Lines 1-343 Link Here
1
#!/usr/bin/perl
2
3
use C4::Context;
4
use Getopt::Long;
5
use C4::Biblio;
6
use C4::AuthoritiesMarc;
7
8
use strict;
9
#use warnings; FIXME - Bug 2505
10
# 
11
# script that fills the nozebra table
12
#
13
#
14
15
$|=1; # flushes output
16
17
# limit for database dumping
18
my $limit;# = "LIMIT 100";
19
my $directory;
20
#my $skip_export;
21
#my $keep_export;
22
#my $reset;
23
#my $biblios;
24
my $authorities;
25
my $sysprefs;
26
my $commit;
27
my $want_help;
28
29
my $result = GetOptions(
30
    'd:s'      => \$directory,
31
#    'reset'      => \$reset,
32
#    's'        => \$skip_export,    # Not used and conflicts with 's' option some lines below for sysprefs!!!
33
#    'k'        => \$keep_export,
34
#    'b'        => \$biblios,
35
#    'a'        => \$authorities,
36
    's'        => \$sysprefs,  # rebuild 'NoZebraIndexes' syspref
37
    'h|help'        => \$want_help,
38
   'commit:f'    => \$commit,
39
    );
40
41
if (not $result or $want_help) {
42
    print_usage();
43
    exit 0;
44
}
45
46
47
sub print_usage {
48
    print <<_USAGE_;
49
$0: reindex MARC bibs and authorities if NOT using Zebra ("NoZebra").
50
51
Use this batch job to reindex all biblio and authority
52
records in your Koha database.  This job is useful
53
only if you are NOT using Zebra ('NoZebra'); if you are 
54
using the 'Zebra'mode, this job should NOT be used.
55
56
Parameters:
57
    -d                      Temporary directory for indexing.
58
                            If not specified, one is automatically
59
                            created.  The export directory
60
                            is automatically deleted unless
61
                            you supply the -k switch.
62
63
    -s                      Rebuild "NoZebraIndexes" System Preference 
64
65
    --help or -h            show this message.
66
_USAGE_
67
}   # END of print_usage sub
68
69
70
my $commitnum = 1000; 
71
$commitnum = $commit if ($commit) ;
72
73
$directory = "export" unless $directory;
74
my $dbh=C4::Context->dbh;
75
$dbh->do("update systempreferences set value=1 where variable='NoZebra'");
76
77
$dbh->do("truncate nozebra");
78
79
my %index = GetNoZebraIndexes();
80
81
if  (!%index || $sysprefs ) {
82
    if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
83
        $dbh->do("UPDATE systempreferences SET value=\"'title' => '200a,200c,200d,200e,225a,225d,225e,225f,225h,225i,225v,500*,501*,503*,510*,512*,513*,514*,515*,516*,517*,518*,519*,520*,530*,531*,532*,540*,541*,545*,604t,610t,605a',
84
        'author' =>'200f,600a,601a,604a,700a,700b,700c,700d,700a,701b,701c,701d,702a,702b,702c,702d,710a,710b,710c,710d,711a,711b,711c,711d,712a,712b,712c,712d',
85
        'isbn' => '010a',
86
        'issn' => '011a',
87
        'biblionumber' =>'0909',
88
        'itemtype' => '200b',
89
        'language' => '101a',
90
        'publisher' => '210c',
91
        'date' => '210d',
92
        'note' => '300a,301a,302a,303a,304a,305a,306az,307a,308a,309a,310a,311a,312a,313a,314a,315a,316a,317a,318a,319a,320a,321a,322a,323a,324a,325a,326a,327a,328a,330a,332a,333a,336a,337a,345a',
93
        'Koha-Auth-Number' => '6009,6019,6029,6039,6049,6059,6069,6109,7009,7019,7029,7109,7119,7129',
94
        'subject' => '600*,601*,606*,610*',
95
        'dewey' => '676a',
96
        'host-item' => '995a,995c',\" where variable='NoZebraIndexes'");
97
        %index = GetNoZebraIndexes();
98
    } elsif (C4::Context->preference('marcflavour') eq 'MARC21') {
99
        $dbh->do("UPDATE systempreferences SET value=\"
100
'title' => '130a,210a,222a,240a,243a,245a,245b,246a,246b,247a,247b,250a,250b,440a,830a',
101
'author' => '100a,100b,100c,100d,110a,111a,111b,111c,111d,245c,700a,710a,711a,800a,810a,811a',
102
'isbn' => '020a',
103
'issn' => '022a',
104
'lccn' => '010a',
105
'biblionumber => '999c',
106
'itemtype' => '942c',
107
'publisher' => '260b',
108
'date' => '260c',
109
'note' => '500a, 501a,504a,505a,508a,511a,518a,520a,521a,522a,524a,526a,530a,533a,538a,541a,546a,555a,556a,562a,563a,583a,585a,582a',
110
'subject' => '600*,610*,611*,630*,650*,651*,653*,654*,655*,662*,690*',
111
'dewey' => '082',
112
'bc' => '952p',
113
'callnum' => '952o',
114
'an' => '6009,6109,6119',
115
'series' => 440*,490*,
116
'host-item' => '9529
117
'shelf' => '952c',
118
'collection' => '9528',
119
\"WHERE variable='NoZebraIndexes'");
120
121
        %index = GetNoZebraIndexes();
122
    }
123
}
124
$|=1;
125
126
$dbh->{AutoCommit} = 0;
127
128
print "***********************************\n";
129
print "***** building BIBLIO indexes *****\n";
130
print "***********************************\n";
131
132
my $sth;
133
$sth=$dbh->prepare("select biblionumber from biblioitems order by biblionumber $limit");
134
$sth->execute();
135
my $i=0;
136
my %result;
137
while (my ($biblionumber) = $sth->fetchrow) {
138
        $i++;
139
        print "\r$i";
140
        my  $record;
141
    eval{
142
            $record = GetMarcBiblio($biblionumber);
143
    };
144
    if($@){
145
            print "  There was some pb getting biblionumber : ".$biblionumber."\n";
146
            next;
147
    }
148
    next unless $record;
149
    # get title of the record (to store the 10 first letters with the index)
150
    my ($titletag,$titlesubfield) = GetMarcFromKohaField('biblio.title', '');
151
    my $title = lc($record->subfield($titletag,$titlesubfield));
152
153
    # remove blancks comma (that could cause problem when decoding the string for CQL retrieval) and regexp specific values
154
    $title =~ s/ |\.|,|;|\[|\]|\(|\)|\*|-|'|=|://g;
155
    # limit to 10 char, should be enough, and limit the DB size
156
    $title = substr($title,0,10);
157
    #parse each field
158
    foreach my $field ($record->fields()) {
159
        #parse each subfield
160
        next if $field->tag <10;
161
        foreach my $subfield ($field->subfields()) {
162
            my $tag = $field->tag();
163
            my $subfieldcode = $subfield->[0];
164
            my $indexed=0;
165
            # check each index to see if the subfield is stored somewhere
166
            # otherwise, store it in __RAW__ index
167
            foreach my $key (keys %index) {
168
                if ($index{$key} =~ /\Q$tag\E\*/ or $index{$key} =~ /\Q$tag$subfieldcode\E/) {
169
                    $indexed=1;
170
                    my $line= lc $subfield->[1];
171
                    # remove meaningless value in the field...
172
                    $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:/ /g;
173
                    # ... and split in words
174
                    foreach (split / /,$line) {
175
                        next unless $_; # skip  empty values (multiple spaces)
176
                        # remove any accented char
177
                        # if the entry is already here, improve weight
178
                        if ($result{$key}->{"$_"} =~ /$biblionumber,\Q$title\E\-(\d);/) {
179
                            my $weight=$1+1;
180
                            $result{$key}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d);//;
181
                            $result{$key}->{"$_"} .= "$biblionumber,$title-$weight;";
182
                        # otherwise, create it, with weight=1
183
                        } else {
184
                            $result{$key}->{"$_"}.="$biblionumber,$title-1;";
185
                        }
186
                    }
187
                }
188
            }
189
            # the subfield is not indexed, store it in __RAW__ index anyway
190
            unless ($indexed) {
191
                my $line= lc $subfield->[1];
192
                $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=/ /g;
193
                foreach (split / /,$line) {
194
                        next unless $_;
195
#                     warn $record->as_formatted."$_ =>".$title;
196
                        if ($result{__RAW__}->{"$_"} =~ /$biblionumber,\Q$title\E\-(\d);/) {
197
                            my $weight=$1+1;
198
#                             $weight++;
199
                            $result{__RAW__}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d);//;
200
                            $result{__RAW__}->{"$_"} .= "$biblionumber,$title-$weight;";
201
                        } else {
202
                            $result{__RAW__}->{"$_"}.="$biblionumber,$title-1;";
203
                        }
204
                }
205
            }
206
        }
207
    }
208
}
209
210
211
print "\nInserting records...\n";
212
$i=0;
213
214
my $commitnum = 100;
215
$dbh->{AutoCommit} = 0;
216
217
$sth = $dbh->prepare("INSERT INTO nozebra (server,indexname,value,biblionumbers) VALUES ('biblioserver',?,?,?)");
218
foreach my $key (keys %result) {
219
    foreach my $index (keys %{$result{$key}}) {
220
        if (length($result{$key}->{$index}) > 1000000) {
221
            print "very long index (".length($result{$key}->{$index}).")for $key / $index. update mySQL config file if you have an error just after this warning (max_paquet_size parameter)\n";
222
        }
223
        print "\r$i";
224
        $i++;
225
        $sth->execute($key,$index,$result{$key}->{$index});
226
        $dbh->commit() if (0 == $i % $commitnum);
227
    }
228
   $dbh->commit() if (0 == $i % $commitnum);
229
}
230
$dbh->commit;
231
232
233
print "\nbiblios done\n";
234
235
print "\n***********************************\n";
236
print "***** building AUTHORITIES indexes *****\n";
237
print "***********************************\n";
238
239
$sth=$dbh->prepare("select authid from auth_header order by authid $limit");
240
$sth->execute();
241
$i=0;
242
%result = ();
243
while (my ($authid) = $sth->fetchrow) {
244
    $i++;
245
    print "\r$i";
246
    my $record;
247
    eval{
248
        $record = GetAuthority($authid);
249
    };
250
    if($@){
251
        print "  There was some pb getting authnumber : ".$authid."\n";
252
        next;
253
    }
254
    
255
    my %index;
256
    # for authorities, the "title" is the $a mainentry
257
    my $authref = C4::AuthoritiesMarc::GetAuthType(C4::AuthoritiesMarc::GetAuthTypeCode($authid));
258
259
    warn "ERROR : authtype undefined for ".$record->as_formatted unless $authref;
260
    my $title = $record->subfield($authref->{auth_tag_to_report},'a');
261
    $index{'mainmainentry'}= $authref->{'auth_tag_to_report'}.'a';
262
    $index{'mainentry'}    = $authref->{'auth_tag_to_report'}.'*';
263
    $index{'auth_type'}    = '152b';
264
265
    # remove blancks comma (that could cause problem when decoding the string for CQL retrieval) and regexp specific values
266
    $title =~ s/ |\.|,|;|\[|\]|\(|\)|\*|-|'|:|=//g;
267
    $title = quotemeta $title;
268
    # limit to 10 char, should be enough, and limit the DB size
269
    $title = substr($title,0,10);
270
    #parse each field
271
    foreach my $field ($record->fields()) {
272
        #parse each subfield
273
        next if $field->tag <10;
274
        foreach my $subfield ($field->subfields()) {
275
            my $tag = $field->tag();
276
            my $subfieldcode = $subfield->[0];
277
            my $indexed=0;
278
            # check each index to see if the subfield is stored somewhere
279
            # otherwise, store it in __RAW__ index
280
            foreach my $key (keys %index) {
281
                if ($index{$key} =~ /$tag\*/ or $index{$key} =~ /$tag$subfieldcode/) {
282
                    $indexed=1;
283
                    my $line= lc $subfield->[1];
284
                    # remove meaningless value in the field...
285
                    $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:/ /g;
286
                    # ... and split in words
287
                    foreach (split / /,$line) {
288
                        next unless $_; # skip  empty values (multiple spaces)
289
                        # if the entry is already here, improve weight
290
                        if ($result{$key}->{"$_"} =~ /$authid,$title\-(\d);/) {
291
                            my $weight=$1+1;
292
                            $result{$key}->{"$_"} =~ s/$authid,$title\-(\d);//;
293
                            $result{$key}->{"$_"} .= "$authid,$title-$weight;";
294
                        # otherwise, create it, with weight=1
295
                        } else {
296
                            $result{$key}->{"$_"}.="$authid,$title-1;";
297
                        }
298
                    }
299
                }
300
            }
301
            # the subfield is not indexed, store it in __RAW__ index anyway
302
            unless ($indexed) {
303
                my $line= lc $subfield->[1];
304
                $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=/ /g;
305
                foreach (split / /,$line) {
306
                        next unless $_;
307
#                     warn $record->as_formatted."$_ =>".$title;
308
                        if ($result{__RAW__}->{"$_"} =~ /$authid,$title\-(\d);/) {
309
                            my $weight=$1+1;
310
#                             $weight++;
311
                            $result{__RAW__}->{"$_"} =~ s/$authid,$title\-(\d);//;
312
                            $result{__RAW__}->{"$_"} .= "$authid,$title-$weight;";
313
                        } else {
314
                            $result{__RAW__}->{"$_"}.="$authid,$title-1;";
315
                        }
316
                }
317
            }
318
        }
319
    }
320
}
321
322
323
324
print "\nInserting...\n";
325
$i=0;
326
327
my $commitnum = 100;
328
$dbh->{AutoCommit} = 0;
329
$sth = $dbh->prepare("INSERT INTO nozebra (server,indexname,value,biblionumbers) VALUES ('authorityserver',?,?,?)");
330
foreach my $key (keys %result) {
331
    foreach my $index (keys %{$result{$key}}) {
332
        if (length($result{$key}->{$index}) > 1000000) {
333
            print "very long index (".length($result{$key}->{$index}).")for $key / $index. update mySQL config file if you have an error just after this warning (max_paquet_size parameter)\n";
334
        }
335
        print "\r$i";
336
        $i++;
337
        $sth->execute($key,$index,$result{$key}->{$index});
338
        $dbh->commit() if (0 == $i % $commitnum);
339
    }
340
   $dbh->commit() if (0 == $i % $commitnum);
341
}
342
$dbh->commit;
343
print "\nauthorities done\n";
(-)a/misc/migration_tools/rebuild_zebra.pl (-3 / +1 lines)
Lines 656-664 sub print_usage { Link Here
656
$0: reindex MARC bibs and/or authorities in Zebra.
656
$0: reindex MARC bibs and/or authorities in Zebra.
657
657
658
Use this batch job to reindex all biblio or authority
658
Use this batch job to reindex all biblio or authority
659
records in your Koha database.  This job is useful
659
records in your Koha database.
660
only if you are using Zebra; if you are using the 'NoZebra'
661
mode, this job should not be used.
662
660
663
Parameters:
661
Parameters:
664
    -b                      index bibliographic records
662
    -b                      index bibliographic records
(-)a/opac/opac-search.pl (-6 / +1 lines)
Lines 483-493 if ($tag) { Link Here
483
    $results_hashref->{biblioserver}->{RECORDS} = \@marclist;
483
    $results_hashref->{biblioserver}->{RECORDS} = \@marclist;
484
    # FIXME: tag search and standard search should work together, not exclusively
484
    # FIXME: tag search and standard search should work together, not exclusively
485
    # FIXME: No facets for tags search.
485
    # FIXME: No facets for tags search.
486
}
487
elsif (C4::Context->preference('NoZebra')) {
488
    eval {
489
        ($error, $results_hashref, $facets) = NZgetRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$query_type,$scan);
490
    };
491
} elsif ($build_grouped_results) {
486
} elsif ($build_grouped_results) {
492
    eval {
487
    eval {
493
        ($error, $results_hashref, $facets) = C4::Search::pazGetRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$query_type,$scan);
488
        ($error, $results_hashref, $facets) = C4::Search::pazGetRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$query_type,$scan);
Lines 662-668 for (my $i=0;$i<@servers;$i++) { Link Here
662
            exit;
657
            exit;
663
        }
658
        }
664
        if ($hits) {
659
        if ($hits) {
665
            if (!C4::Context->preference('NoZebra') && !$build_grouped_results) {
660
            if ( !$build_grouped_results ) {
666
                # We build the encrypted list of first OPACnumSearchResults biblios to pass with the search criteria for paging on opac-detail
661
                # We build the encrypted list of first OPACnumSearchResults biblios to pass with the search criteria for paging on opac-detail
667
                $pasarParams .= '&amp;listBiblios=';
662
                $pasarParams .= '&amp;listBiblios=';
668
                my $j = 0;
663
                my $j = 0;
(-)a/t/db_dependent/Search.t (-3 / +1 lines)
Lines 39-47 $contextmodule->mock('_new_dbh', sub { Link Here
39
    return $dbh });
39
    return $dbh });
40
$contextmodule->mock('preference', sub {
40
$contextmodule->mock('preference', sub {
41
    my ($self, $pref) = @_;
41
    my ($self, $pref) = @_;
42
    if ($pref eq 'NoZebra') {
42
    if ($pref eq 'marcflavour') {
43
        return 0;
44
    } elsif ($pref eq 'marcflavour') {
45
        return 'MARC21';
43
        return 'MARC21';
46
    } elsif ($pref eq 'QueryStemming') {
44
    } elsif ($pref eq 'QueryStemming') {
47
        return $QueryStemming;
45
        return $QueryStemming;
(-)a/t/db_dependent/lib/KohaTest.pm (-8 lines)
Lines 144-150 sub startup_15_truncate_tables : Test( startup => 1 ) { Link Here
144
#                               matchpoint_components
144
#                               matchpoint_components
145
#                               matchpoints
145
#                               matchpoints
146
#                               notifys
146
#                               notifys
147
#                               nozebra
148
#                               old_issues
147
#                               old_issues
149
#                               old_reserves
148
#                               old_reserves
150
#                               opac_news
149
#                               opac_news
Lines 203-209 sub startup_15_truncate_tables : Test( startup => 1 ) { Link Here
203
                              issuingrules
202
                              issuingrules
204
                              matchchecks
203
                              matchchecks
205
                              notifys
204
                              notifys
206
                              nozebra
207
                              old_issues
205
                              old_issues
208
                              old_reserves
206
                              old_reserves
209
                              overduerules
207
                              overduerules
Lines 606-614 Useful for test routines that need to do a Link Here
606
lot of indexing without having to wait for
604
lot of indexing without having to wait for
607
zebraqueue.
605
zebraqueue.
608
606
609
In NoZebra model, this only marks zebraqueue
610
done - the records should already be indexed.
611
612
=cut
607
=cut
613
608
614
sub reindex_marc {
609
sub reindex_marc {
Lines 618-625 sub reindex_marc { Link Here
618
    my $dbh = C4::Context->dbh();
613
    my $dbh = C4::Context->dbh();
619
    $dbh->do("UPDATE zebraqueue SET done = 1 WHERE done = 0");
614
    $dbh->do("UPDATE zebraqueue SET done = 1 WHERE done = 0");
620
615
621
    return if C4::Context->preference('NoZebra');
622
623
    my $directory = tempdir(CLEANUP => 1);
616
    my $directory = tempdir(CLEANUP => 1);
624
    foreach my $record_type qw(biblio authority) {
617
    foreach my $record_type qw(biblio authority) {
625
        mkdir "$directory/$record_type";
618
        mkdir "$directory/$record_type";
Lines 728-734 sub create_test_database { Link Here
728
    my ($fwk_language, $installed_list) = $installer->load_sql_in_order($all_languages, @$list);
721
    my ($fwk_language, $installed_list) = $installer->load_sql_in_order($all_languages, @$list);
729
    $installer->set_version_syspref();
722
    $installer->set_version_syspref();
730
    $installer->set_marcflavour_syspref('MARC21');
723
    $installer->set_marcflavour_syspref('MARC21');
731
    $installer->set_indexing_engine(0);
732
    diag 'database created.'
724
    diag 'database created.'
733
}
725
}
734
726
(-)a/t/db_dependent/lib/KohaTest/Biblio.pm (-3 lines)
Lines 46-54 sub methods : Test( 1 ) { Link Here
46
                       get_koha_field_from_marc
46
                       get_koha_field_from_marc
47
                       TransformMarcToKohaOneField
47
                       TransformMarcToKohaOneField
48
                       ModZebra
48
                       ModZebra
49
                       GetNoZebraIndexes
50
                       _DelBiblioNoZebra
51
                       _AddBiblioNoZebra
52
                       _find_value
49
                       _find_value
53
                       _koha_marc_update_bib_ids
50
                       _koha_marc_update_bib_ids
54
                       _koha_marc_update_biblioitem_cn_sort
51
                       _koha_marc_update_biblioitem_cn_sort
(-)a/t/db_dependent/lib/KohaTest/Biblio/GetNoZebraIndexes.pm (-72 lines)
Lines 1-72 Link Here
1
package KohaTest::Biblio::GetNoZebraIndexes;
2
use base qw( KohaTest::Biblio );
3
4
use strict;
5
use warnings;
6
7
use Test::More;
8
9
use C4::Biblio;
10
11
=head2 STARTUP METHODS
12
13
These get run once, before the main test methods in this module
14
15
=cut
16
17
18
=head2 TEST METHODS
19
20
standard test methods
21
22
=head3 
23
24
=cut
25
    
26
sub returns_expected_hashref : Test(2) {
27
    my $self = shift;
28
29
    my %nzi = C4::Biblio::GetNoZebraIndexes();
30
    ok( scalar keys %nzi, 'got some keys from GetNoZebraIndexes' );
31
32
    my %expected = (
33
        'title'        => '130a,210a,222a,240a,243a,245a,245b,246a,246b,247a,247b,250a,250b,440a,830a',
34
        'author'       => '100a,100b,100c,100d,110a,111a,111b,111c,111d,245c,700a,710a,711a,800a,810a,811a',
35
        'isbn'         => '020a',
36
        'issn'         => '022a',
37
        'lccn'         => '010a',
38
        'biblionumber' => '999c',
39
        'itemtype'     => '942c',
40
        'publisher'    => '260b',
41
        'date'         => '260c',
42
        'note'         => '500a,501a,504a,505a,508a,511a,518a,520a,521a,522a,524a,526a,530a,533a,538a,541a,546a,555a,556a,562a,563a,583a,585a,582a',
43
        'subject'      => '600*,610*,611*,630*,650*,651*,653*,654*,655*,662*,690*',
44
        'dewey'        => '082',
45
        'bc'           => '952p',
46
        'callnum'      => '952o',
47
        'an'           => '6009,6109,6119',
48
        'homebranch'   => '952a,952c'
49
    );
50
    is_deeply( \%nzi, \%expected, 'GetNoZebraIndexes returns the expected hashref' );
51
}
52
53
=head2 HELPER METHODS
54
55
These methods are used by other test methods, but
56
are not meant to be called directly.
57
58
=cut
59
60
=cut
61
62
63
=head2 SHUTDOWN METHODS
64
65
These get run once, after the main test methods in this module
66
67
=head3 
68
69
=cut
70
71
72
1;
(-)a/t/db_dependent/lib/KohaTest/Installer.pm (-1 lines)
Lines 23-29 sub methods : Test( 1 ) { Link Here
23
                       load_db_schema 
23
                       load_db_schema 
24
                       load_sql_in_order 
24
                       load_sql_in_order 
25
                       set_marcflavour_syspref 
25
                       set_marcflavour_syspref 
26
                       set_indexing_engine 
27
                       set_version_syspref 
26
                       set_version_syspref 
28
                       load_sql 
27
                       load_sql 
29
    );
28
    );
(-)a/t/db_dependent/lib/KohaTest/Search.pm (-6 lines)
Lines 23-34 sub methods : Test( 1 ) { Link Here
23
                      _build_weighted_query
23
                      _build_weighted_query
24
                      buildQuery
24
                      buildQuery
25
                      searchResults
25
                      searchResults
26
                      NZgetRecords
27
                      NZanalyse
28
                      NZoperatorAND
29
                      NZoperatorOR
30
                      NZoperatorNOT
31
                      NZorder
32
                );
26
                );
33
    
27
    
34
    can_ok( $self->testing_class, @methods );    
28
    can_ok( $self->testing_class, @methods );    
(-)a/t/db_dependent/lib/KohaTest/Search/NoZebra.pm (-236 lines)
Lines 1-235 Link Here
1
package KohaTest::Search::NoZebra;
2
use base qw( KohaTest::Search );
3
4
use strict;
5
use warnings;
6
7
use Test::More;
8
9
use MARC::Record;
10
11
use C4::Search;
12
use C4::Biblio;
13
use C4::Context;
14
15
=head2 STARTUP METHODS
16
17
These get run once, before the main test methods in this module
18
19
=cut
20
21
=head3 startup_50_init_nozebra
22
23
Turn on NoZebra mode, for now, assumes and requires
24
that the test database has started out using Zebra.
25
26
=cut
27
28
sub startup_50_init_nozebra : Test( startup => 3 ) {
29
    my $using_nozebra = C4::Context->preference('NoZebra');
30
    ok(!$using_nozebra, "starting out using Zebra");
31
    my $dbh = C4::Context->dbh;
32
    $dbh->do("UPDATE systempreferences SET value=1 WHERE variable='NoZebra'");
33
    $dbh->do("UPDATE systempreferences SET value=0 WHERE variable in ('QueryFuzzy','QueryWeightFields','QueryStemming')");
34
    C4::Context->clear_syspref_cache();
35
    $using_nozebra = C4::Context->preference('NoZebra');
36
    ok($using_nozebra, "switched to NoZebra");
37
38
    my $sth = $dbh->prepare("SELECT COUNT(*) FROM nozebra");
39
    $sth->execute;
40
    my ($count) = $sth->fetchrow_array;
41
    $sth->finish;
42
    cmp_ok($count, '==', 0, "NoZebra index starts off empty");
43
}
44
45
sub startup_51_add_bibs : Test( startup => 2 ) {
46
    my $self = shift;
47
48
    my $bib1 = MARC::Record->new();
49
    $bib1->leader('     nam a22     7a 4500');
50
    $bib1->append_fields(
51
        MARC::Field->new('010', ' ', ' ', a => 'lccn001'), 
52
        MARC::Field->new('020', ' ', ' ', a => 'isbn001'), 
53
        MARC::Field->new('022', ' ', ' ', a => 'issn001'), 
54
        MARC::Field->new('100', ' ', ' ', a => 'Cat, Felix T.'),
55
        MARC::Field->new('245', ' ', ' ', a => 'Of mice and men :', b=> 'a history'),
56
    );
57
    my $bib2 = MARC::Record->new();
58
    $bib2->leader('     nam a22     7a 4500');
59
    $bib2->append_fields(
60
        MARC::Field->new('010', ' ', ' ', a => 'lccn002'), 
61
        MARC::Field->new('020', ' ', ' ', a => 'isbn002'), 
62
        MARC::Field->new('022', ' ', ' ', a => 'issn002'), 
63
        MARC::Field->new('100', ' ', ' ', a => 'Dog, Rover T.'),
64
        MARC::Field->new('245', ' ', ' ', a => 'Of mice and men :', b=> 'a digression'),
65
    );
66
67
    my $dbh = C4::Context->dbh;
68
    my $count_sth = $dbh->prepare("SELECT COUNT(*) FROM nozebra");
69
    my $count;
70
    my ($bib1_bibnum, $bib1_bibitemnum) = AddBiblio($bib1, '');
71
    $count_sth->execute;
72
    ($count) = $count_sth->fetchrow_array;
73
    cmp_ok($count, '==', 14, "correct number of new words indexed"); # tokens + biblionumber + __RAW__
74
75
    my ($bib2_bibnum, $bib2_bibitemnum) = AddBiblio($bib2, '');
76
    $count_sth->execute;
77
    ($count) = $count_sth->fetchrow_array;
78
    cmp_ok($count, '==', 22, "correct number of new words indexed"); # tokens + biblionumber + __RAW__
79
80
    push @{ $self->{nozebra_test_bibs} }, $bib1_bibnum, $bib2_bibnum;
81
}
82
83
=head2 TEST METHODS
84
85
Standard test methods
86
87
=cut
88
89
sub basic_searches_via_nzanalyze : Test( 28 ) {
90
    my $self = shift;
91
    my ($bib1_bibnum, $bib2_bibnum) = @{ $self->{nozebra_test_bibs} };
92
    
93
    my $results = C4::Search::NZanalyse('foobar');
94
    ok(!defined($results), "no hits on 'foobar'");
95
96
    $results = C4::Search::NZanalyse('dog');
97
    my ($hits, @bibnumbers) = parse_nzanalyse($results);
98
    cmp_ok($hits, '==', 1, "one hit on 'dog'");
99
    is($bib2_bibnum, $bibnumbers[0], "correct hit on 'dog'");
100
101
    $results = C4::Search::NZanalyse('au=dog');
102
    ($hits, @bibnumbers) = parse_nzanalyse($results);
103
    cmp_ok($hits, '==', 1, "one hit on 'au=dog'");
104
    is($bib2_bibnum, $bibnumbers[0], "correct hit on 'au=dog'");
105
106
    $results = C4::Search::NZanalyse('isbn=dog');
107
    ($hits, @bibnumbers) = parse_nzanalyse($results);
108
    cmp_ok($hits, '==', 0, "zero hits on 'isbn=dog'");
109
110
    $results = C4::Search::NZanalyse('cat');
111
    ($hits, @bibnumbers) = parse_nzanalyse($results);
112
    cmp_ok($hits, '==', 1, "one hit on 'cat'");
113
    is($bib1_bibnum, $bibnumbers[0], "correct hit on 'cat'");
114
115
    $results = C4::Search::NZanalyse('cat and dog');
116
    ($hits, @bibnumbers) = parse_nzanalyse($results);
117
    cmp_ok($hits, '==', 0, "zero hits on 'cat and dog'");
118
119
    $results = C4::Search::NZanalyse('cat or dog');
120
    ($hits, @bibnumbers) = parse_nzanalyse($results);
121
    cmp_ok($hits, '==', 2, "two hits on 'cat or dog'");
122
    is_deeply([ sort @bibnumbers ], [ sort($bib1_bibnum, $bib2_bibnum) ], "correct hits on 'cat or dog'");
123
124
    $results = C4::Search::NZanalyse('mice and men');
125
    ($hits, @bibnumbers) = parse_nzanalyse($results);
126
    cmp_ok($hits, '==', 2, "two hits on 'mice and men'");
127
    is_deeply([ sort @bibnumbers ], [ sort($bib1_bibnum, $bib2_bibnum) ], "correct hits on 'mice and men'");
128
129
    $results = C4::Search::NZanalyse('title=digression or issn=issn001');
130
    ($hits, @bibnumbers) = parse_nzanalyse($results);
131
    cmp_ok($hits, '==', 2, "two hits on 'title=digression or issn=issn001'");
132
    is_deeply([ sort @bibnumbers ], [ sort($bib1_bibnum, $bib2_bibnum) ], "correct hits on 'title=digression or issn=issn001'");
133
134
    $results = C4::Search::NZanalyse('title=digression and issn=issn002');
135
    ($hits, @bibnumbers) = parse_nzanalyse($results);
136
    cmp_ok($hits, '==', 1, "two hits on 'title=digression and issn=issn002'");
137
    is($bib2_bibnum, $bibnumbers[0], "correct hit on 'title=digression and issn=issn002'");
138
139
    $results = C4::Search::NZanalyse('mice not men');
140
    ($hits, @bibnumbers) = parse_nzanalyse($results);
141
    cmp_ok($hits, '==', 0, "zero hits on 'mice not men'");
142
143
    $results = C4::Search::NZanalyse('mice not dog');
144
    ($hits, @bibnumbers) = parse_nzanalyse($results);
145
    cmp_ok($hits, '==', 1, "one hit on 'mice not dog'");
146
    is($bib1_bibnum, $bibnumbers[0], "correct hit on 'mice not dog'");
147
148
    $results = C4::Search::NZanalyse('isbn > a');
149
    ($hits, @bibnumbers) = parse_nzanalyse($results);
150
    cmp_ok($hits, '==', 2, "two hits on 'isbn > a'");
151
    is_deeply([ sort @bibnumbers ], [ sort($bib1_bibnum, $bib2_bibnum) ], "correct hits on 'isbn > a'");
152
153
    $results = C4::Search::NZanalyse('isbn < z');
154
    ($hits, @bibnumbers) = parse_nzanalyse($results);
155
    cmp_ok($hits, '==', 2, "two hits on 'isbn < z'");
156
    is_deeply([ sort @bibnumbers ], [ sort($bib1_bibnum, $bib2_bibnum) ], "correct hits on 'isbn < z'");
157
158
    $results = C4::Search::NZanalyse('isbn > isbn001');
159
    ($hits, @bibnumbers) = parse_nzanalyse($results);
160
    cmp_ok($hits, '==', 1, "one hit on 'isbn > isbn001'");
161
    is($bib2_bibnum, $bibnumbers[0], "correct hit on 'isbn > isbn001'");
162
163
    $results = C4::Search::NZanalyse('isbn>=isbn001');
164
    ($hits, @bibnumbers) = parse_nzanalyse($results);
165
    cmp_ok($hits, '==', 2, "two hits on 'isbn>=isbn001'");
166
    is_deeply([ sort @bibnumbers ], [ sort($bib1_bibnum, $bib2_bibnum) ], "correct hits on 'isbn>=isbn001'");
167
}
168
169
sub parse_nzanalyse {
170
    my $results = shift;
171
    my @bibnumbers = ();
172
    if (defined $results) {
173
        # NZanalyze currently has a funky way of returning results -
174
        # it does not guarantee that a biblionumber occurs only
175
        # once in the results string.  Hence we must remove
176
        # duplicates, like NZorder (inefficently) does
177
        my %hash;
178
        @bibnumbers = grep { ++$hash{$_} == 1 }  map { my @f = split /,/, $_; $f[0]; } split /;/, $results;
179
    }
180
    return scalar(@bibnumbers), @bibnumbers;
181
}
182
183
=head2 SHUTDOWN METHODS
184
185
These get run once, after all of the main tests methods in this module
186
187
=cut
188
189
sub shutdown_49_remove_bibs : Test( shutdown => 4 ) {
190
    my $self = shift;
191
    my ($bib1_bibnum, $bib2_bibnum) = @{ $self->{nozebra_test_bibs} };
192
193
    my $dbh = C4::Context->dbh;
194
    my $count_sth = $dbh->prepare("SELECT COUNT(*) FROM nozebra");
195
    my $count;
196
197
    my $error = DelBiblio($bib2_bibnum);
198
    ok(!defined($error), "deleted bib $bib2_bibnum");
199
    $count_sth->execute;
200
    ($count) = $count_sth->fetchrow_array;
201
    TODO: { local $TODO = 'nothing actually gets deleted from nozebra currently';
202
    cmp_ok($count, '==', 14, "correct number of words indexed after bib $bib2_bibnum deleted"); 
203
    }
204
205
    $error = DelBiblio($bib1_bibnum);
206
    ok(!defined($error), "deleted bib $bib1_bibnum");
207
    $count_sth->execute;
208
    ($count) = $count_sth->fetchrow_array;
209
    TODO: { local $TODO = 'nothing actually gets deleted from nozebra currently';
210
    cmp_ok($count, '==', 0, "no entries left in nozebra after bib $bib1_bibnum deleted"); 
211
    }
212
213
    delete $self->{nozebra_test_bibs};
214
}
215
216
sub shutdown_50_init_nozebra : Test( shutdown => 3 ) {
217
    my $using_nozebra = C4::Context->preference('NoZebra');
218
    ok($using_nozebra, "still in NoZebra mode");
219
    my $dbh = C4::Context->dbh;
220
    $dbh->do("UPDATE systempreferences SET value=0 WHERE variable='NoZebra'");
221
    $dbh->do("UPDATE systempreferences SET value=1 WHERE variable in ('QueryFuzzy','QueryWeightFields','QueryStemming')");
222
    C4::Context->clear_syspref_cache();
223
    $using_nozebra = C4::Context->preference('NoZebra');
224
    ok(!$using_nozebra, "switched to Zebra");
225
226
    # FIXME
227
    $dbh->do("DELETE FROM nozebra");
228
    my $sth = $dbh->prepare("SELECT COUNT(*) FROM nozebra");
229
    $sth->execute;
230
    my ($count) = $sth->fetchrow_array;
231
    $sth->finish;
232
    cmp_ok($count, '==', 0, "NoZebra index finishes up empty");
233
}
234
235
1;
236
- 

Return to bug 7440