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 (-278 / +186 lines)
Lines 109-413 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
    my $query;
113
    
113
    my $qpquery = '';
114
        #
114
    my $QParser;
115
        # build the query
115
    $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser'));
116
        #
116
    my $attr = '';
117
        my $query;
117
        # the marclist may contain "mainentry". In this case, search the tag_to_report, that depends on
118
        # the authtypecode. Then, search on $a of this tag_to_report
119
        # also store main entry MARC tag, to extract it at end of search
120
    my $mainentrytag;
121
    ##first set the authtype search and may be multiple authorities
122
    if ($authtypecode) {
123
        my $n=0;
124
        my @authtypecode;
118
        my @auths=split / /,$authtypecode ;
125
        my @auths=split / /,$authtypecode ;
119
        foreach my  $auth (@auths){
126
        foreach my  $auth (@auths){
120
            $query .="AND auth_type= $auth ";
127
            $query .=" \@attr 1=authtype \@attr 5=100 ".$auth; ##No truncation on authtype
128
                push @authtypecode ,$auth;
129
            $n++;
121
        }
130
        }
122
        $query =~ s/^AND //;
131
        if ($n>1){
123
        my $dosearch;
132
            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
        }
133
        }
144
        #
134
        if ($QParser) {
145
        # do the query (if we had some search term
135
            $qpquery .= '(authtype:' . join('|| authtype:', @auths) . ')';
146
        #
136
        }
147
        if ($dosearch) {
137
    }
148
#             warn "QUERY : $query";
138
    
149
            my $result = C4::Search::NZanalyse($query,'authorityserver');
139
    my $dosearch;
150
#             warn "result : $result";
140
    my $and=" \@and " ;
151
            my %result;
141
    my $q2;
152
            foreach (split /;/,$result) {
142
    my $attr_cnt = 0;
153
                my ($authid,$title) = split /,/,$_;
143
    for(my $i = 0 ; $i <= $#{$value} ; $i++)
154
                # hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
144
    {
155
                # and we don't want to get only 1 result for each of them !!!
145
        if (@$value[$i]){
156
                # hint & speed improvement : we can order without reading the record
146
            if ( @$tags[$i] eq "mainmainentry" ) {
157
                # so order, and read records only for the requested page !
147
                $attr = " \@attr 1=Heading-Main ";
158
                $result{$title.$authid}=$authid;
159
            }
148
            }
160
            # sort the hash and return the same structure as GetRecords (Zebra querying)
149
            elsif ( @$tags[$i] eq "mainentry" ) {
161
            my @listresult = ();
150
                $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
            }
151
            }
176
            # limit the $results_per_page to result size if it's more
152
            elsif ( @$tags[$i] eq "match" ) {
177
            $length = $numbers-$offset if $numbers < ($offset+$length);
153
                $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
            }
154
            }
198
            return (\@finalresult, $numbers);
155
            elsif ( @$tags[$i] eq "match-heading" ) {
199
        } else {
156
                $attr = " \@attr 1=Match-heading ";
200
            return;
157
            }
201
        }
158
            elsif ( @$tags[$i] eq "see-from" ) {
202
    } else {
159
                $attr = " \@attr 1=Match-heading-see-from ";
203
        my $query;
160
            }
204
        my $qpquery = '';
161
            elsif ( @$tags[$i] eq "thesaurus" ) {
205
        my $QParser;
162
                $attr = " \@attr 1=Subject-heading-thesaurus ";
206
        $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser'));
163
            }
207
        my $attr = '';
164
            else { # Assume any if no index was specified
208
            # the marclist may contain "mainentry". In this case, search the tag_to_report, that depends on
165
                $attr = " \@attr 1=Any ";
209
            # the authtypecode. Then, search on $a of this tag_to_report
210
            # also store main entry MARC tag, to extract it at end of search
211
        my $mainentrytag;
212
        ##first set the authtype search and may be multiple authorities
213
        if ($authtypecode) {
214
            my $n=0;
215
            my @authtypecode;
216
            my @auths=split / /,$authtypecode ;
217
            foreach my  $auth (@auths){
218
                $query .=" \@attr 1=authtype \@attr 5=100 ".$auth; ##No truncation on authtype
219
                    push @authtypecode ,$auth;
220
                $n++;
221
            }
166
            }
222
            if ($n>1){
167
            if ( @$operator[$i] eq 'is' ) {
223
                while ($n>1){$query= "\@or ".$query;$n--;}
168
                $attr .= " \@attr 4=1  \@attr 5=100 "
169
                  ; ##Phrase, No truncation,all of subfield field must match
170
            }
171
            elsif ( @$operator[$i] eq "=" ) {
172
                $attr .= " \@attr 4=107 ";    #Number Exact match
173
            }
174
            elsif ( @$operator[$i] eq "start" ) {
175
                $attr .= " \@attr 3=2 \@attr 4=1 \@attr 5=1 "
176
                  ;    #Firstinfield Phrase, Right truncated
177
            }
178
            elsif ( @$operator[$i] eq "exact" ) {
179
                $attr .= " \@attr 4=1  \@attr 5=100 \@attr 6=3 "
180
                  ; ##Phrase, No truncation,all of subfield field must match
181
            }
182
            else {
183
                $attr .= " \@attr 5=1 \@attr 4=6 "
184
                  ;    ## Word list, right truncated, anywhere
185
                  if ($sortby eq 'Relevance') {
186
                      $attr .= "\@attr 2=102 ";
187
                  }
224
            }
188
            }
189
            @$value[$i] =~ s/"/\\"/g; # Escape the double-quotes in the search value
190
            $attr =$attr."\"".@$value[$i]."\"";
191
            $q2 .=$attr;
192
            $dosearch=1;
193
            ++$attr_cnt;
225
            if ($QParser) {
194
            if ($QParser) {
226
                $qpquery .= '(authtype:' . join('|| authtype:', @auths) . ')';
195
                $qpquery .= " $tags->[$i]:\"$value->[$i]\"";
227
            }
196
            }
228
        }
197
        }#if value
229
        
198
    }
230
        my $dosearch;
199
    ##Add how many queries generated
231
        my $and=" \@and " ;
200
    if (defined $query && $query=~/\S+/){
232
        my $q2;
201
      $query= $and x $attr_cnt . $query . (defined $q2 ? $q2 : '');
233
        my $attr_cnt = 0;
202
    } else {
234
        for(my $i = 0 ; $i <= $#{$value} ; $i++)
203
      $query= $q2;
235
        {
204
    }
236
            if (@$value[$i]){
205
    ## Adding order
237
                if ( @$tags[$i] eq "mainmainentry" ) {
206
    #$query=' @or  @attr 7=2 @attr 1=Heading 0 @or  @attr 7=1 @attr 1=Heading 1'.$query if ($sortby eq "HeadingDsc");
238
                    $attr = " \@attr 1=Heading-Main ";
207
    my $orderstring;
239
                }
208
    if ($sortby eq 'HeadingAsc') {
240
                elsif ( @$tags[$i] eq "mainentry" ) {
209
        $orderstring = '@attr 7=1 @attr 1=Heading 0';
241
                    $attr = " \@attr 1=Heading ";
210
    } elsif ($sortby eq 'HeadingDsc') {
242
                }
211
        $orderstring = '@attr 7=2 @attr 1=Heading 0';
243
                elsif ( @$tags[$i] eq "match" ) {
212
    } elsif ($sortby eq 'AuthidAsc') {
244
                    $attr = " \@attr 1=Match ";
213
        $orderstring = '@attr 7=1 @attr 4=109 @attr 1=Local-Number 0';
245
                }
214
    } elsif ($sortby eq 'AuthidDsc') {
246
                elsif ( @$tags[$i] eq "match-heading" ) {
215
        $orderstring = '@attr 7=2 @attr 4=109 @attr 1=Local-Number 0';
247
                    $attr = " \@attr 1=Match-heading ";
216
    }
248
                }
217
    if ($QParser) {
249
                elsif ( @$tags[$i] eq "see-from" ) {
218
        $qpquery .= ' all:all' unless $value->[0];
250
                    $attr = " \@attr 1=Match-heading-see-from ";
251
                }
252
                elsif ( @$tags[$i] eq "thesaurus" ) {
253
                    $attr = " \@attr 1=Subject-heading-thesaurus ";
254
                }
255
                else { # Assume any if no index was specified
256
                    $attr = " \@attr 1=Any ";
257
                }
258
                if ( @$operator[$i] eq 'is' ) {
259
                    $attr .= " \@attr 4=1  \@attr 5=100 "
260
                      ; ##Phrase, No truncation,all of subfield field must match
261
                }
262
                elsif ( @$operator[$i] eq "=" ) {
263
                    $attr .= " \@attr 4=107 ";    #Number Exact match
264
                }
265
                elsif ( @$operator[$i] eq "start" ) {
266
                    $attr .= " \@attr 3=2 \@attr 4=1 \@attr 5=1 "
267
                      ;    #Firstinfield Phrase, Right truncated
268
                }
269
                elsif ( @$operator[$i] eq "exact" ) {
270
                    $attr .= " \@attr 4=1  \@attr 5=100 \@attr 6=3 "
271
                      ; ##Phrase, No truncation,all of subfield field must match
272
                }
273
                else {
274
                    $attr .= " \@attr 5=1 \@attr 4=6 "
275
                      ;    ## Word list, right truncated, anywhere
276
                      if ($sortby eq 'Relevance') {
277
                          $attr .= "\@attr 2=102 ";
278
                      }
279
                }
280
                @$value[$i] =~ s/"/\\"/g; # Escape the double-quotes in the search value
281
                $attr =$attr."\"".@$value[$i]."\"";
282
                $q2 .=$attr;
283
                $dosearch=1;
284
                ++$attr_cnt;
285
                if ($QParser) {
286
                    $qpquery .= " $tags->[$i]:\"$value->[$i]\"";
287
                }
288
            }#if value
289
        }
290
        ##Add how many queries generated
291
        if (defined $query && $query=~/\S+/){
292
          $query= $and x $attr_cnt . $query . (defined $q2 ? $q2 : '');
293
        } else {
294
          $query= $q2;
295
        }
296
        ## Adding order
297
        #$query=' @or  @attr 7=2 @attr 1=Heading 0 @or  @attr 7=1 @attr 1=Heading 1'.$query if ($sortby eq "HeadingDsc");
298
        my $orderstring;
299
        if ($sortby eq 'HeadingAsc') {
300
            $orderstring = '@attr 7=1 @attr 1=Heading 0';
301
        } elsif ($sortby eq 'HeadingDsc') {
302
            $orderstring = '@attr 7=2 @attr 1=Heading 0';
303
        } elsif ($sortby eq 'AuthidAsc') {
304
            $orderstring = '@attr 7=1 @attr 4=109 @attr 1=Local-Number 0';
305
        } elsif ($sortby eq 'AuthidDsc') {
306
            $orderstring = '@attr 7=2 @attr 4=109 @attr 1=Local-Number 0';
307
        }
308
        if ($QParser) {
309
            $qpquery .= ' all:all' unless $value->[0];
310
219
311
            if ( $value->[0] =~ m/^qp=(.*)$/ ) {
220
        if ( $value->[0] =~ m/^qp=(.*)$/ ) {
312
                $qpquery = $1;
221
            $qpquery = $1;
313
            }
222
        }
314
223
315
            $qpquery .= " #$sortby";
224
        $qpquery .= " #$sortby";
316
225
317
            $QParser->parse( $qpquery );
226
        $QParser->parse( $qpquery );
318
            $query = $QParser->target_syntax('authorityserver');
227
        $query = $QParser->target_syntax('authorityserver');
319
        } else {
228
    } else {
320
            $query=($query?$query:"\@attr 1=_ALLRECORDS \@attr 2=103 ''");
229
        $query=($query?$query:"\@attr 1=_ALLRECORDS \@attr 2=103 ''");
321
            $query="\@or $orderstring $query" if $orderstring;
230
        $query="\@or $orderstring $query" if $orderstring;
322
        }
231
    }
323
232
324
        $offset=0 unless $offset;
233
    $offset=0 unless $offset;
325
        my $counter = $offset;
234
    my $counter = $offset;
326
        $length=10 unless $length;
235
    $length=10 unless $length;
327
        my @oAuth;
236
    my @oAuth;
328
        my $i;
237
    my $i;
329
        $oAuth[0]=C4::Context->Zconn("authorityserver" , 1);
238
    $oAuth[0]=C4::Context->Zconn("authorityserver" , 1);
330
        my $Anewq= new ZOOM::Query::PQF($query,$oAuth[0]);
239
    my $Anewq= new ZOOM::Query::PQF($query,$oAuth[0]);
331
        my $oAResult;
240
    my $oAResult;
332
        $oAResult= $oAuth[0]->search($Anewq) ; 
241
    $oAResult= $oAuth[0]->search($Anewq) ; 
333
        while (($i = ZOOM::event(\@oAuth)) != 0) {
242
    while (($i = ZOOM::event(\@oAuth)) != 0) {
334
            my $ev = $oAuth[$i-1]->last_event();
243
        my $ev = $oAuth[$i-1]->last_event();
335
            last if $ev == ZOOM::Event::ZEND;
244
        last if $ev == ZOOM::Event::ZEND;
336
        }
245
    }
337
        my($error, $errmsg, $addinfo, $diagset) = $oAuth[0]->error_x();
246
    my($error, $errmsg, $addinfo, $diagset) = $oAuth[0]->error_x();
338
        if ($error) {
247
    if ($error) {
339
            warn  "oAuth error: $errmsg ($error) $addinfo $diagset\n";
248
        warn  "oAuth error: $errmsg ($error) $addinfo $diagset\n";
340
            goto NOLUCK;
249
        goto NOLUCK;
341
        }
250
    }
342
        
251
    
343
        my $nbresults;
252
    my $nbresults;
344
        $nbresults=$oAResult->size();
253
    $nbresults=$oAResult->size();
345
        my $nremains=$nbresults;    
254
    my $nremains=$nbresults;    
346
        my @result = ();
255
    my @result = ();
347
        my @finalresult = ();
256
    my @finalresult = ();
348
        
257
    
349
        if ($nbresults>0){
258
    if ($nbresults>0){
259
    
260
    ##Find authid and linkid fields
261
    ##we may be searching multiple authoritytypes.
262
    ## FIXME this assumes that all authid and linkid fields are the same for all authority types
263
    # my ($authidfield,$authidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.authid",$authtypecode[0]);
264
    # my ($linkidfield,$linkidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.linkid",$authtypecode[0]);
265
        while (($counter < $nbresults) && ($counter < ($offset + $length))) {
350
        
266
        
351
        ##Find authid and linkid fields
267
        ##Here we have to extract MARC record and $authid from ZEBRA AUTHORITIES
352
        ##we may be searching multiple authoritytypes.
268
        my $rec=$oAResult->record($counter);
353
        ## FIXME this assumes that all authid and linkid fields are the same for all authority types
269
        my $marcdata=$rec->raw();
354
        # my ($authidfield,$authidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.authid",$authtypecode[0]);
270
        my $authrecord;
355
        # my ($linkidfield,$linkidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.linkid",$authtypecode[0]);
271
        my $separator=C4::Context->preference('authoritysep');
356
            while (($counter < $nbresults) && ($counter < ($offset + $length))) {
272
        $authrecord = MARC::File::USMARC::decode($marcdata);
357
            
273
        my $authid=$authrecord->field('001')->data(); 
358
            ##Here we have to extract MARC record and $authid from ZEBRA AUTHORITIES
274
        my %newline;
359
            my $rec=$oAResult->record($counter);
275
        $newline{authid} = $authid;
360
            my $marcdata=$rec->raw();
276
        if ( !$skipmetadata ) {
361
            my $authrecord;
277
            my $summary =
362
            my $separator=C4::Context->preference('authoritysep');
278
              BuildSummary( $authrecord, $authid, $authtypecode );
363
            $authrecord = MARC::File::USMARC::decode($marcdata);
279
            my $query_auth_tag =
364
            my $authid=$authrecord->field('001')->data(); 
365
            my %newline;
366
            $newline{authid} = $authid;
367
            if ( !$skipmetadata ) {
368
                my $summary =
369
                  BuildSummary( $authrecord, $authid, $authtypecode );
370
                my $query_auth_tag =
371
"SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?";
280
"SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?";
372
                my $sth = $dbh->prepare($query_auth_tag);
281
            my $sth = $dbh->prepare($query_auth_tag);
373
                $sth->execute($authtypecode);
282
            $sth->execute($authtypecode);
374
                my $auth_tag_to_report = $sth->fetchrow;
283
            my $auth_tag_to_report = $sth->fetchrow;
375
                my $reported_tag;
284
            my $reported_tag;
376
                my $mainentry = $authrecord->field($auth_tag_to_report);
285
            my $mainentry = $authrecord->field($auth_tag_to_report);
377
                if ($mainentry) {
286
            if ($mainentry) {
378
287
379
                    foreach ( $mainentry->subfields() ) {
288
                foreach ( $mainentry->subfields() ) {
380
                        $reported_tag .= '$' . $_->[0] . $_->[1];
289
                    $reported_tag .= '$' . $_->[0] . $_->[1];
381
                    }
382
                }
290
                }
383
                my $thisauthtype = GetAuthType(GetAuthTypeCode($authid));
384
                unless (defined $thisauthtype) {
385
                    $thisauthtype = GetAuthType($authtypecode) if $authtypecode;
386
                }
387
                $newline{authtype}     = defined($thisauthtype) ?
388
                                            $thisauthtype->{'authtypetext'} : '';
389
                $newline{summary}      = $summary;
390
                $newline{even}         = $counter % 2;
391
                $newline{reported_tag} = $reported_tag;
392
            }
291
            }
393
            $counter++;
292
            my $thisauthtype = GetAuthType(GetAuthTypeCode($authid));
394
            push @finalresult, \%newline;
293
            unless (defined $thisauthtype) {
395
            }## while counter
294
                $thisauthtype = GetAuthType($authtypecode) if $authtypecode;
396
            ###
397
            if (! $skipmetadata) {
398
                for (my $z=0; $z<@finalresult; $z++){
399
                    my  $count=CountUsage($finalresult[$z]{authid});
400
                    $finalresult[$z]{used}=$count;
401
                }# all $z's
402
            }
295
            }
296
            $newline{authtype}     = defined($thisauthtype) ?
297
                                        $thisauthtype->{'authtypetext'} : '';
298
            $newline{summary}      = $summary;
299
            $newline{even}         = $counter % 2;
300
            $newline{reported_tag} = $reported_tag;
301
        }
302
        $counter++;
303
        push @finalresult, \%newline;
304
        }## while counter
305
        ###
306
        if (! $skipmetadata) {
307
            for (my $z=0; $z<@finalresult; $z++){
308
                my  $count=CountUsage($finalresult[$z]{authid});
309
                $finalresult[$z]{used}=$count;
310
            }# all $z's
311
        }
403
312
404
        }## if nbresult
313
    }## if nbresult
405
        NOLUCK:
314
    NOLUCK:
406
        $oAResult->destroy();
315
    $oAResult->destroy();
407
        # $oAuth[0]->destroy();
316
    # $oAuth[0]->destroy();
408
        
317
    
409
        return (\@finalresult, $nbresults);
318
    return (\@finalresult, $nbresults);
410
    }
411
}
319
}
412
320
413
=head2 CountUsage 
321
=head2 CountUsage 
(-)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 2760-2766 sub TransformMarcToKohaOneField { Link Here
2760
2751
2761
=head2 ModZebra
2752
=head2 ModZebra
2762
2753
2763
  ModZebra( $biblionumber, $op, $server, $oldRecord, $newRecord );
2754
  ModZebra( $biblionumber, $op, $server );
2764
2755
2765
$biblionumber is the biblionumber we want to index
2756
$biblionumber is the biblionumber we want to index
2766
2757
Lines 2768-2866 $op is specialUpdate or delete, and is used to know what we want to do Link Here
2768
2759
2769
$server is the server that we want to update
2760
$server is the server that we want to update
2770
2761
2771
$oldRecord is the MARC::Record containing the previous version of the record.  This is used only when 
2772
NoZebra=1, as NoZebra indexing needs to know the previous version of a record in order to
2773
do an update.
2774
2775
$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.
2776
2777
=cut
2762
=cut
2778
2763
2779
sub ModZebra {
2764
sub ModZebra {
2780
###Accepts a $server variable thus we can use it for biblios authorities or other zebra dbs
2765
###Accepts a $server variable thus we can use it for biblios authorities or other zebra dbs
2781
    my ( $biblionumber, $op, $server, $oldRecord, $newRecord ) = @_;
2766
    my ( $biblionumber, $op, $server ) = @_;
2782
    my $dbh = C4::Context->dbh;
2767
    my $dbh = C4::Context->dbh;
2783
2768
2784
    # true ModZebra commented until indexdata fixes zebraDB crashes (it seems they occur on multiple updates
2769
    # true ModZebra commented until indexdata fixes zebraDB crashes (it seems they occur on multiple updates
2785
    # at the same time
2770
    # at the same time
2786
    # replaced by a zebraqueue table, that is filled with ModZebra to run.
2771
    # replaced by a zebraqueue table, that is filled with ModZebra to run.
2787
    # the table is emptied by misc/cronjobs/zebraqueue_start.pl script
2772
    # the table is emptied by rebuild_zebra.pl script (using the -z switch)
2788
2773
2789
    if ( C4::Context->preference("NoZebra") ) {
2774
    my $check_sql = "SELECT COUNT(*) FROM zebraqueue
2790
2775
                     WHERE server = ?
2791
        # lock the nozebra table : we will read index lines, update them in Perl process
2776
                     AND   biblio_auth_number = ?
2792
        # and write everything in 1 transaction.
2777
                     AND   operation = ?
2793
        # lock the table to avoid someone else overwriting what we are doing
2778
                     AND   done = 0";
2794
        $dbh->do('LOCK TABLES nozebra WRITE,biblio WRITE,biblioitems WRITE, systempreferences WRITE, auth_types WRITE, auth_header WRITE, auth_subfield_structure READ');
2779
    my $check_sth = $dbh->prepare_cached($check_sql);
2795
        my %result;    # the result hash that will be built by deletion / add, and written on mySQL at the end, to improve speed
2780
    $check_sth->execute( $server, $biblionumber, $op );
2796
        if ( $op eq 'specialUpdate' ) {
2781
    my ($count) = $check_sth->fetchrow_array;
2797
2782
    $check_sth->finish();
2798
            # OK, we have to add or update the record
2783
    if ( $count == 0 ) {
2799
            # 1st delete (virtually, in indexes), if record actually exists
2784
        my $sth = $dbh->prepare("INSERT INTO zebraqueue  (biblio_auth_number,server,operation) VALUES(?,?,?)");
2800
            if ($oldRecord) {
2785
        $sth->execute( $biblionumber, $server, $op );
2801
                %result = _DelBiblioNoZebra( $biblionumber, $oldRecord, $server );
2786
        $sth->finish;
2802
            }
2803
2804
            # ... add the record
2805
            %result = _AddBiblioNoZebra( $biblionumber, $newRecord, $server, %result );
2806
        } else {
2807
2808
            # it's a deletion, delete the record...
2809
            # warn "DELETE the record $biblionumber on $server".$record->as_formatted;
2810
            %result = _DelBiblioNoZebra( $biblionumber, $oldRecord, $server );
2811
        }
2812
2813
        # ok, now update the database...
2814
        my $sth = $dbh->prepare("UPDATE nozebra SET biblionumbers=? WHERE server=? AND indexname=? AND value=?");
2815
        foreach my $key ( keys %result ) {
2816
            foreach my $index ( keys %{ $result{$key} } ) {
2817
                $sth->execute( $result{$key}->{$index}, $server, $key, $index );
2818
            }
2819
        }
2820
        $dbh->do('UNLOCK TABLES');
2821
    } else {
2822
2823
        #
2824
        # we use zebra, just fill zebraqueue table
2825
        #
2826
        my $check_sql = "SELECT COUNT(*) FROM zebraqueue 
2827
                         WHERE server = ?
2828
                         AND   biblio_auth_number = ?
2829
                         AND   operation = ?
2830
                         AND   done = 0";
2831
        my $check_sth = $dbh->prepare_cached($check_sql);
2832
        $check_sth->execute( $server, $biblionumber, $op );
2833
        my ($count) = $check_sth->fetchrow_array;
2834
        $check_sth->finish();
2835
        if ( $count == 0 ) {
2836
            my $sth = $dbh->prepare("INSERT INTO zebraqueue  (biblio_auth_number,server,operation) VALUES(?,?,?)");
2837
            $sth->execute( $biblionumber, $server, $op );
2838
            $sth->finish;
2839
        }
2840
    }
2787
    }
2841
}
2788
}
2842
2789
2843
=head2 GetNoZebraIndexes
2844
2845
  %indexes = GetNoZebraIndexes;
2846
2847
return the data from NoZebraIndexes syspref.
2848
2849
=cut
2850
2851
sub GetNoZebraIndexes {
2852
    my $no_zebra_indexes = C4::Context->preference('NoZebraIndexes');
2853
    my %indexes;
2854
  INDEX: foreach my $line ( split /['"],[\n\r]*/, $no_zebra_indexes ) {
2855
        $line =~ /(.*)=>(.*)/;
2856
        my $index  = $1;    # initial ' or " is removed afterwards
2857
        my $fields = $2;
2858
        $index  =~ s/'|"|\s//g;
2859
        $fields =~ s/'|"|\s//g;
2860
        $indexes{$index} = $fields;
2861
    }
2862
    return %indexes;
2863
}
2864
2790
2865
=head2 EmbedItemsInMarcBiblio
2791
=head2 EmbedItemsInMarcBiblio
2866
2792
Lines 2899-3166 sub EmbedItemsInMarcBiblio { Link Here
2899
2825
2900
=head1 INTERNAL FUNCTIONS
2826
=head1 INTERNAL FUNCTIONS
2901
2827
2902
=head2 _DelBiblioNoZebra($biblionumber,$record,$server);
2903
2904
function to delete a biblio in NoZebra indexes
2905
This function does NOT delete anything in database : it reads all the indexes entries
2906
that have to be deleted & delete them in the hash
2907
2908
The SQL part is done either :
2909
 - after the Add if we are modifying a biblio (delete + add again)
2910
 - immediatly after this sub if we are doing a true deletion.
2911
2912
$server can be 'biblioserver' or 'authorityserver' : it indexes biblios or authorities (in the same table, $server being part of the table itself
2913
2914
=cut
2915
2916
sub _DelBiblioNoZebra {
2917
    my ( $biblionumber, $record, $server ) = @_;
2918
2919
    # Get the indexes
2920
    my $dbh = C4::Context->dbh;
2921
2922
    # Get the indexes
2923
    my %index;
2924
    my $title;
2925
    if ( $server eq 'biblioserver' ) {
2926
        %index = GetNoZebraIndexes;
2927
2928
        # get title of the record (to store the 10 first letters with the index)
2929
        my ( $titletag, $titlesubfield ) = GetMarcFromKohaField( 'biblio.title', '' );    # FIXME: should be GetFrameworkCode($biblionumber) ??
2930
        $title = lc( $record->subfield( $titletag, $titlesubfield ) );
2931
    } else {
2932
2933
        # for authorities, the "title" is the $a mainentry
2934
        my ( $auth_type_tag, $auth_type_sf ) = C4::AuthoritiesMarc::get_auth_type_location();
2935
        my $authref = C4::AuthoritiesMarc::GetAuthType( $record->subfield( $auth_type_tag, $auth_type_sf ) );
2936
        warn "ERROR : authtype undefined for " . $record->as_formatted unless $authref;
2937
        $title = $record->subfield( $authref->{auth_tag_to_report}, 'a' );
2938
        $index{'mainmainentry'} = $authref->{'auth_tag_to_report'} . 'a';
2939
        $index{'mainentry'}     = $authref->{'auth_tag_to_report'} . '*';
2940
        $index{'auth_type'}     = "${auth_type_tag}${auth_type_sf}";
2941
    }
2942
2943
    my %result;
2944
2945
    # remove blancks comma (that could cause problem when decoding the string for CQL retrieval) and regexp specific values
2946
    $title =~ s/ |,|;|\[|\]|\(|\)|\*|-|'|=//g;
2947
2948
    # limit to 10 char, should be enough, and limit the DB size
2949
    $title = substr( $title, 0, 10 );
2950
2951
    #parse each field
2952
    my $sth2 = $dbh->prepare('SELECT biblionumbers FROM nozebra WHERE server=? AND indexname=? AND value=?');
2953
    foreach my $field ( $record->fields() ) {
2954
2955
        #parse each subfield
2956
        next if $field->tag < 10;
2957
        foreach my $subfield ( $field->subfields() ) {
2958
            my $tag          = $field->tag();
2959
            my $subfieldcode = $subfield->[0];
2960
            my $indexed      = 0;
2961
2962
            # check each index to see if the subfield is stored somewhere
2963
            # otherwise, store it in __RAW__ index
2964
            foreach my $key ( keys %index ) {
2965
2966
                #                 warn "examining $key index : ".$index{$key}." for $tag $subfieldcode";
2967
                if ( $index{$key} =~ /$tag\*/ or $index{$key} =~ /$tag$subfieldcode/ ) {
2968
                    $indexed = 1;
2969
                    my $line = lc $subfield->[1];
2970
2971
                    # remove meaningless value in the field...
2972
                    $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:/ /g;
2973
2974
                    # ... and split in words
2975
                    foreach ( split / /, $line ) {
2976
                        next unless $_;    # skip  empty values (multiple spaces)
2977
                                           # if the entry is already here, do nothing, the biblionumber has already be removed
2978
                        unless ( defined( $result{$key}->{$_} ) && ( $result{$key}->{$_} =~ /$biblionumber,$title\-(\d);/ ) ) {
2979
2980
                            # get the index value if it exist in the nozebra table and remove the entry, otherwise, do nothing
2981
                            $sth2->execute( $server, $key, $_ );
2982
                            my $existing_biblionumbers = $sth2->fetchrow;
2983
2984
                            # it exists
2985
                            if ($existing_biblionumbers) {
2986
2987
                                #                                 warn " existing for $key $_: $existing_biblionumbers";
2988
                                $result{$key}->{$_} = $existing_biblionumbers;
2989
                                $result{$key}->{$_} =~ s/$biblionumber,$title\-(\d);//;
2990
                            }
2991
                        }
2992
                    }
2993
                }
2994
            }
2995
2996
            # the subfield is not indexed, store it in __RAW__ index anyway
2997
            unless ($indexed) {
2998
                my $line = lc $subfield->[1];
2999
                $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:/ /g;
3000
3001
                # ... and split in words
3002
                foreach ( split / /, $line ) {
3003
                    next unless $_;    # skip  empty values (multiple spaces)
3004
                                       # if the entry is already here, do nothing, the biblionumber has already be removed
3005
                    unless ( $result{'__RAW__'}->{$_} =~ /$biblionumber,$title\-(\d);/ ) {
3006
3007
                        # get the index value if it exist in the nozebra table and remove the entry, otherwise, do nothing
3008
                        $sth2->execute( $server, '__RAW__', $_ );
3009
                        my $existing_biblionumbers = $sth2->fetchrow;
3010
3011
                        # it exists
3012
                        if ($existing_biblionumbers) {
3013
                            $result{'__RAW__'}->{$_} = $existing_biblionumbers;
3014
                            $result{'__RAW__'}->{$_} =~ s/$biblionumber,$title\-(\d);//;
3015
                        }
3016
                    }
3017
                }
3018
            }
3019
        }
3020
    }
3021
    return %result;
3022
}
3023
3024
=head2 _AddBiblioNoZebra
3025
3026
  _AddBiblioNoZebra($biblionumber, $record, $server, %result);
3027
3028
function to add a biblio in NoZebra indexes
3029
3030
=cut
3031
3032
sub _AddBiblioNoZebra {
3033
    my ( $biblionumber, $record, $server, %result ) = @_;
3034
    my $dbh = C4::Context->dbh;
3035
3036
    # Get the indexes
3037
    my %index;
3038
    my $title;
3039
    if ( $server eq 'biblioserver' ) {
3040
        %index = GetNoZebraIndexes;
3041
3042
        # get title of the record (to store the 10 first letters with the index)
3043
        my ( $titletag, $titlesubfield ) = GetMarcFromKohaField( 'biblio.title', '' );    # FIXME: should be GetFrameworkCode($biblionumber) ??
3044
        $title = lc( $record->subfield( $titletag, $titlesubfield ) );
3045
    } else {
3046
3047
        # warn "server : $server";
3048
        # for authorities, the "title" is the $a mainentry
3049
        my ( $auth_type_tag, $auth_type_sf ) = C4::AuthoritiesMarc::get_auth_type_location();
3050
        my $authref = C4::AuthoritiesMarc::GetAuthType( $record->subfield( $auth_type_tag, $auth_type_sf ) );
3051
        warn "ERROR : authtype undefined for " . $record->as_formatted unless $authref;
3052
        $title = $record->subfield( $authref->{auth_tag_to_report}, 'a' );
3053
        $index{'mainmainentry'} = $authref->{auth_tag_to_report} . 'a';
3054
        $index{'mainentry'}     = $authref->{auth_tag_to_report} . '*';
3055
        $index{'auth_type'}     = "${auth_type_tag}${auth_type_sf}";
3056
    }
3057
3058
    # remove blancks comma (that could cause problem when decoding the string for CQL retrieval) and regexp specific values
3059
    $title =~ s/ |\.|,|;|\[|\]|\(|\)|\*|-|'|:|=|\r|\n//g;
3060
3061
    # limit to 10 char, should be enough, and limit the DB size
3062
    $title = substr( $title, 0, 10 );
3063
3064
    #parse each field
3065
    my $sth2 = $dbh->prepare('SELECT biblionumbers FROM nozebra WHERE server=? AND indexname=? AND value=?');
3066
    foreach my $field ( $record->fields() ) {
3067
3068
        #parse each subfield
3069
        ###FIXME: impossible to index a 001-009 value with NoZebra
3070
        next if $field->tag < 10;
3071
        foreach my $subfield ( $field->subfields() ) {
3072
            my $tag          = $field->tag();
3073
            my $subfieldcode = $subfield->[0];
3074
            my $indexed      = 0;
3075
3076
            #             warn "INDEXING :".$subfield->[1];
3077
            # check each index to see if the subfield is stored somewhere
3078
            # otherwise, store it in __RAW__ index
3079
            foreach my $key ( keys %index ) {
3080
3081
                #                 warn "examining $key index : ".$index{$key}." for $tag $subfieldcode";
3082
                if ( $index{$key} =~ /$tag\*/ or $index{$key} =~ /$tag$subfieldcode/ ) {
3083
                    $indexed = 1;
3084
                    my $line = lc $subfield->[1];
3085
3086
                    # remove meaningless value in the field...
3087
                    $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:|\r|\n/ /g;
3088
3089
                    # ... and split in words
3090
                    foreach ( split / /, $line ) {
3091
                        next unless $_;    # skip  empty values (multiple spaces)
3092
                                           # if the entry is already here, improve weight
3093
3094
                        #                         warn "managing $_";
3095
                        if ( exists $result{$key}->{$_} && $result{$key}->{"$_"} =~ /$biblionumber,\Q$title\E\-(\d+);/ ) {
3096
                            my $weight = $1 + 1;
3097
                            $result{$key}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//g;
3098
                            $result{$key}->{"$_"} .= "$biblionumber,$title-$weight;";
3099
                        } else {
3100
3101
                            # get the value if it exist in the nozebra table, otherwise, create it
3102
                            $sth2->execute( $server, $key, $_ );
3103
                            my $existing_biblionumbers = $sth2->fetchrow;
3104
3105
                            # it exists
3106
                            if ($existing_biblionumbers) {
3107
                                $result{$key}->{"$_"} = $existing_biblionumbers;
3108
                                my $weight = defined $1 ? $1 + 1 : 1;
3109
                                $result{$key}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//g;
3110
                                $result{$key}->{"$_"} .= "$biblionumber,$title-$weight;";
3111
3112
                                # create a new ligne for this entry
3113
                            } else {
3114
3115
                                #                             warn "INSERT : $server / $key / $_";
3116
                                $dbh->do( 'INSERT INTO nozebra SET server=' . $dbh->quote($server) . ', indexname=' . $dbh->quote($key) . ',value=' . $dbh->quote($_) );
3117
                                $result{$key}->{"$_"} .= "$biblionumber,$title-1;";
3118
                            }
3119
                        }
3120
                    }
3121
                }
3122
            }
3123
3124
            # the subfield is not indexed, store it in __RAW__ index anyway
3125
            unless ($indexed) {
3126
                my $line = lc $subfield->[1];
3127
                $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:|\r|\n/ /g;
3128
3129
                # ... and split in words
3130
                foreach ( split / /, $line ) {
3131
                    next unless $_;    # skip  empty values (multiple spaces)
3132
                                       # if the entry is already here, improve weight
3133
                    my $tmpstr = $result{'__RAW__'}->{"$_"} || "";
3134
                    if ( $tmpstr =~ /$biblionumber,\Q$title\E\-(\d+);/ ) {
3135
                        my $weight = $1 + 1;
3136
                        $result{'__RAW__'}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//;
3137
                        $result{'__RAW__'}->{"$_"} .= "$biblionumber,$title-$weight;";
3138
                    } else {
3139
3140
                        # get the value if it exist in the nozebra table, otherwise, create it
3141
                        $sth2->execute( $server, '__RAW__', $_ );
3142
                        my $existing_biblionumbers = $sth2->fetchrow;
3143
3144
                        # it exists
3145
                        if ($existing_biblionumbers) {
3146
                            $result{'__RAW__'}->{"$_"} = $existing_biblionumbers;
3147
                            my $weight = ( $1 ? $1 : 0 ) + 1;
3148
                            $result{'__RAW__'}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//;
3149
                            $result{'__RAW__'}->{"$_"} .= "$biblionumber,$title-$weight;";
3150
3151
                            # create a new ligne for this entry
3152
                        } else {
3153
                            $dbh->do( 'INSERT INTO nozebra SET server=' . $dbh->quote($server) . ',  indexname="__RAW__",value=' . $dbh->quote($_) );
3154
                            $result{'__RAW__'}->{"$_"} .= "$biblionumber,$title-1;";
3155
                        }
3156
                    }
3157
                }
3158
            }
3159
        }
3160
    }
3161
    return %result;
3162
}
3163
3164
=head2 _koha_marc_update_bib_ids
2828
=head2 _koha_marc_update_bib_ids
3165
2829
3166
2830
Lines 3641-3657 sub ModBiblioMarc { Link Here
3641
      $f005->update(sprintf("%4d%02d%02d%02d%02d%04.1f",@a)) if $f005;
3305
      $f005->update(sprintf("%4d%02d%02d%02d%02d%04.1f",@a)) if $f005;
3642
    }
3306
    }
3643
3307
3644
    my $oldRecord;
3645
    if ( C4::Context->preference("NoZebra") ) {
3646
3647
        # only NoZebra indexing needs to have
3648
        # the previous version of the record
3649
        $oldRecord = GetMarcBiblio($biblionumber);
3650
    }
3651
    $sth = $dbh->prepare("UPDATE biblioitems SET marc=?,marcxml=? WHERE biblionumber=?");
3308
    $sth = $dbh->prepare("UPDATE biblioitems SET marc=?,marcxml=? WHERE biblionumber=?");
3652
    $sth->execute( $record->as_usmarc(), $record->as_xml_record($encoding), $biblionumber );
3309
    $sth->execute( $record->as_usmarc(), $record->as_xml_record($encoding), $biblionumber );
3653
    $sth->finish;
3310
    $sth->finish;
3654
    ModZebra( $biblionumber, "specialUpdate", "biblioserver", $oldRecord, $record );
3311
    ModZebra( $biblionumber, "specialUpdate", "biblioserver" );
3655
    return $biblionumber;
3312
    return $biblionumber;
3656
}
3313
}
3657
3314
(-)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 / +66 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 223-313 $template->param(result=>\@results); Link Here
223
sub SimpleSearch {
222
sub SimpleSearch {
224
    my ( $query, $offset, $max_results, $servers )  = @_;
223
    my ( $query, $offset, $max_results, $servers )  = @_;
225
224
226
    if ( C4::Context->preference('NoZebra') ) {
225
    return ( 'No query entered', undef, undef ) unless $query;
227
        my $result = NZorder( NZanalyse($query) )->{'biblioserver'};
226
    # FIXME hardcoded value. See catalog/search.pl & opac-search.pl too.
228
        my $search_result =
227
    my @servers = defined ( $servers ) ? @$servers : ( 'biblioserver' );
229
          (      $result->{hits}
228
    my @zoom_queries;
230
              && $result->{hits} > 0 ? $result->{'RECORDS'} : [] );
229
    my @tmpresults;
231
        return ( undef, $search_result, scalar($result->{hits}) );
230
    my @zconns;
232
    }
231
    my $results = [];
233
    else {
232
    my $total_hits = 0;
234
        return ( 'No query entered', undef, undef ) unless $query;
235
        # FIXME hardcoded value. See catalog/search.pl & opac-search.pl too.
236
        my @servers = defined ( $servers ) ? @$servers : ( 'biblioserver' );
237
        my @zoom_queries;
238
        my @tmpresults;
239
        my @zconns;
240
        my $results = [];
241
        my $total_hits = 0;
242
233
243
        my $QParser;
234
    my $QParser;
244
        $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser') && ! ($query =~ m/\w,\w|\w=\w/));
235
    $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser') && ! ($query =~ m/\w,\w|\w=\w/));
245
236
246
        # Initialize & Search Zebra
237
    # Initialize & Search Zebra
247
        for ( my $i = 0 ; $i < @servers ; $i++ ) {
238
    for ( my $i = 0 ; $i < @servers ; $i++ ) {
248
            eval {
239
        eval {
249
                $zconns[$i] = C4::Context->Zconn( $servers[$i], 1 );
240
            $zconns[$i] = C4::Context->Zconn( $servers[$i], 1 );
250
                if ($QParser) {
241
            if ($QParser) {
251
                    $query =~ s/=/:/g;
242
                $query =~ s/=/:/g;
252
                    $QParser->parse( $query );
243
                $QParser->parse( $query );
253
                    $query = $QParser->target_syntax($servers[$i]);
244
                $query = $QParser->target_syntax($servers[$i]);
254
                    $zoom_queries[$i] = new ZOOM::Query::PQF( $query, $zconns[$i]);
245
                $zoom_queries[$i] = new ZOOM::Query::PQF( $query, $zconns[$i]);
255
                } else {
246
            } else {
256
                    $query =~ s/:/=/g;
247
                $query =~ s/:/=/g;
257
                    $zoom_queries[$i] = new ZOOM::Query::CCL2RPN( $query, $zconns[$i]);
248
                $zoom_queries[$i] = new ZOOM::Query::CCL2RPN( $query, $zconns[$i]);
258
                }
259
                $tmpresults[$i] = $zconns[$i]->search( $zoom_queries[$i] );
260
261
                # error handling
262
                my $error =
263
                    $zconns[$i]->errmsg() . " ("
264
                  . $zconns[$i]->errcode() . ") "
265
                  . $zconns[$i]->addinfo() . " "
266
                  . $zconns[$i]->diagset();
267
268
                return ( $error, undef, undef ) if $zconns[$i]->errcode();
269
            };
270
            if ($@) {
271
272
                # caught a ZOOM::Exception
273
                my $error =
274
                    $@->message() . " ("
275
                  . $@->code() . ") "
276
                  . $@->addinfo() . " "
277
                  . $@->diagset();
278
                warn $error." for query: $query";
279
                return ( $error, undef, undef );
280
            }
249
            }
281
        }
250
            $tmpresults[$i] = $zconns[$i]->search( $zoom_queries[$i] );
282
251
283
        _ZOOM_event_loop(
252
            # error handling
284
            \@zconns,
253
            my $error =
285
            \@tmpresults,
254
                $zconns[$i]->errmsg() . " ("
286
            sub {
255
              . $zconns[$i]->errcode() . ") "
287
                my ($i, $size) = @_;
256
              . $zconns[$i]->addinfo() . " "
288
                my $first_record = defined($offset) ? $offset + 1 : 1;
257
              . $zconns[$i]->diagset();
289
                my $hits = $tmpresults[ $i - 1 ]->size();
290
                $total_hits += $hits;
291
                my $last_record = $hits;
292
                if ( defined $max_results && $offset + $max_results < $hits ) {
293
                    $last_record = $offset + $max_results;
294
                }
295
258
296
                for my $j ( $first_record .. $last_record ) {
259
            return ( $error, undef, undef ) if $zconns[$i]->errcode();
297
                    my $record =
260
        };
298
                      $tmpresults[ $i - 1 ]->record( $j - 1 )->raw()
261
        if ($@) {
299
                      ;    # 0 indexed
262
300
                    push @{$results}, $record;
263
            # caught a ZOOM::Exception
301
                }
264
            my $error =
265
                $@->message() . " ("
266
              . $@->code() . ") "
267
              . $@->addinfo() . " "
268
              . $@->diagset();
269
            warn $error." for query: $query";
270
            return ( $error, undef, undef );
271
        }
272
    }
273
274
    _ZOOM_event_loop(
275
        \@zconns,
276
        \@tmpresults,
277
        sub {
278
            my ($i, $size) = @_;
279
            my $first_record = defined($offset) ? $offset + 1 : 1;
280
            my $hits = $tmpresults[ $i - 1 ]->size();
281
            $total_hits += $hits;
282
            my $last_record = $hits;
283
            if ( defined $max_results && $offset + $max_results < $hits ) {
284
                $last_record = $offset + $max_results;
302
            }
285
            }
303
        );
304
286
305
        foreach my $zoom_query (@zoom_queries) {
287
            for my $j ( $first_record .. $last_record ) {
306
            $zoom_query->destroy();
288
                my $record =
289
                  $tmpresults[ $i - 1 ]->record( $j - 1 )->raw()
290
                  ;    # 0 indexed
291
                push @{$results}, $record;
292
            }
307
        }
293
        }
294
    );
308
295
309
        return ( undef, $results, $total_hits );
296
    foreach my $zoom_query (@zoom_queries) {
297
        $zoom_query->destroy();
310
    }
298
    }
299
300
    return ( undef, $results, $total_hits );
311
}
301
}
312
302
313
=head2 getRecords
303
=head2 getRecords
Lines 2171-2772 sub SearchAcquisitions{ Link Here
2171
    $qdataacquisitions->finish;
2161
    $qdataacquisitions->finish;
2172
    return \@loopacquisitions;
2162
    return \@loopacquisitions;
2173
}
2163
}
2174
#----------------------------------------------------------------------
2175
#
2176
# Non-Zebra GetRecords#
2177
#----------------------------------------------------------------------
2178
2179
=head2 NZgetRecords
2180
2181
  NZgetRecords has the same API as zera getRecords, even if some parameters are not managed
2182
2183
=cut
2184
2185
sub NZgetRecords {
2186
    my (
2187
        $query,            $simple_query, $sort_by_ref,    $servers_ref,
2188
        $results_per_page, $offset,       $expanded_facet, $branches,
2189
        $query_type,       $scan
2190
    ) = @_;
2191
    warn "query =$query" if $DEBUG;
2192
    my $result = NZanalyse($query);
2193
    warn "results =$result" if $DEBUG;
2194
    return ( undef,
2195
        NZorder( $result, @$sort_by_ref[0], $results_per_page, $offset ),
2196
        undef );
2197
}
2198
2199
=head2 NZanalyse
2200
2201
  NZanalyse : get a CQL string as parameter, and returns a list of biblionumber;title,biblionumber;title,...
2202
  the list is built from an inverted index in the nozebra SQL table
2203
  note that title is here only for convenience : the sorting will be very fast when requested on title
2204
  if the sorting is requested on something else, we will have to reread all results, and that may be longer.
2205
2206
=cut
2207
2208
sub NZanalyse {
2209
    my ( $string, $server ) = @_;
2210
#     warn "---------"       if $DEBUG;
2211
    warn " NZanalyse" if $DEBUG;
2212
#     warn "---------"       if $DEBUG;
2213
2214
 # $server contains biblioserver or authorities, depending on what we search on.
2215
 #warn "querying : $string on $server";
2216
    $server = 'biblioserver' unless $server;
2217
2218
# if we have a ", replace the content to discard temporarily any and/or/not inside
2219
    my $commacontent;
2220
    if ( $string =~ /"/ ) {
2221
        $string =~ s/"(.*?)"/__X__/;
2222
        $commacontent = $1;
2223
        warn "commacontent : $commacontent" if $DEBUG;
2224
    }
2225
2226
# split the query string in 3 parts : X AND Y means : $left="X", $operand="AND" and $right="Y"
2227
# then, call again NZanalyse with $left and $right
2228
# (recursive until we find a leaf (=> something without and/or/not)
2229
# delete repeated operator... Would then go in infinite loop
2230
    while ( $string =~ s/( and| or| not| AND| OR| NOT)\1/$1/g ) {
2231
    }
2232
2233
    #process parenthesis before.
2234
    if ( $string =~ /^\s*\((.*)\)(( and | or | not | AND | OR | NOT )(.*))?/ ) {
2235
        my $left     = $1;
2236
        my $right    = $4;
2237
        my $operator = lc($3);   # FIXME: and/or/not are operators, not operands
2238
        warn
2239
"dealing w/parenthesis before recursive sub call. left :$left operator:$operator right:$right"
2240
          if $DEBUG;
2241
        my $leftresult = NZanalyse( $left, $server );
2242
        if ($operator) {
2243
            my $rightresult = NZanalyse( $right, $server );
2244
2245
            # OK, we have the results for right and left part of the query
2246
            # depending of operand, intersect, union or exclude both lists
2247
            # to get a result list
2248
            if ( $operator eq ' and ' ) {
2249
                return NZoperatorAND($leftresult,$rightresult);
2250
            }
2251
            elsif ( $operator eq ' or ' ) {
2252
2253
                # just merge the 2 strings
2254
                return $leftresult . $rightresult;
2255
            }
2256
            elsif ( $operator eq ' not ' ) {
2257
                return NZoperatorNOT($leftresult,$rightresult);
2258
            }
2259
        }
2260
        else {
2261
# this error is impossible, because of the regexp that isolate the operand, but just in case...
2262
            return $leftresult;
2263
        }
2264
    }
2265
    warn "string :" . $string if $DEBUG;
2266
    my $left = "";
2267
    my $right = "";
2268
    my $operator = "";
2269
    if ($string =~ /(.*?)( and | or | not | AND | OR | NOT )(.*)/) {
2270
        $left     = $1;
2271
        $right    = $3;
2272
        $operator = lc($2);    # FIXME: and/or/not are operators, not operands
2273
    }
2274
    warn "no parenthesis. left : $left operator: $operator right: $right"
2275
      if $DEBUG;
2276
2277
    # it's not a leaf, we have a and/or/not
2278
    if ($operator) {
2279
2280
        # reintroduce comma content if needed
2281
        $right =~ s/__X__/"$commacontent"/ if $commacontent;
2282
        $left  =~ s/__X__/"$commacontent"/ if $commacontent;
2283
        warn "node : $left / $operator / $right\n" if $DEBUG;
2284
        my $leftresult  = NZanalyse( $left,  $server );
2285
        my $rightresult = NZanalyse( $right, $server );
2286
        warn " leftresult : $leftresult" if $DEBUG;
2287
        warn " rightresult : $rightresult" if $DEBUG;
2288
        # OK, we have the results for right and left part of the query
2289
        # depending of operand, intersect, union or exclude both lists
2290
        # to get a result list
2291
        if ( $operator eq ' and ' ) {
2292
            return NZoperatorAND($leftresult,$rightresult);
2293
        }
2294
        elsif ( $operator eq ' or ' ) {
2295
2296
            # just merge the 2 strings
2297
            return $leftresult . $rightresult;
2298
        }
2299
        elsif ( $operator eq ' not ' ) {
2300
            return NZoperatorNOT($leftresult,$rightresult);
2301
        }
2302
        else {
2303
2304
# this error is impossible, because of the regexp that isolate the operand, but just in case...
2305
            die "error : operand unknown : $operator for $string";
2306
        }
2307
2308
        # it's a leaf, do the real SQL query and return the result
2309
    }
2310
    else {
2311
        $string =~ s/__X__/"$commacontent"/ if $commacontent;
2312
        $string =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|&|\+|\*|\// /g;
2313
        #remove trailing blank at the beginning
2314
        $string =~ s/^ //g;
2315
        warn "leaf:$string" if $DEBUG;
2316
2317
        # parse the string in in operator/operand/value again
2318
        my $left = "";
2319
        my $operator = "";
2320
        my $right = "";
2321
        if ($string =~ /(.*)(>=|<=)(.*)/) {
2322
            $left     = $1;
2323
            $operator = $2;
2324
            $right    = $3;
2325
        } else {
2326
            $left = $string;
2327
        }
2328
#         warn "handling leaf... left:$left operator:$operator right:$right"
2329
#           if $DEBUG;
2330
        unless ($operator) {
2331
            if ($string =~ /(.*)(>|<|=)(.*)/) {
2332
                $left     = $1;
2333
                $operator = $2;
2334
                $right    = $3;
2335
                warn
2336
    "handling unless (operator)... left:$left operator:$operator right:$right"
2337
                if $DEBUG;
2338
            } else {
2339
                $left = $string;
2340
            }
2341
        }
2342
        my $results;
2343
2344
# strip adv, zebra keywords, currently not handled in nozebra: wrdl, ext, phr...
2345
        $left =~ s/ .*$//;
2346
2347
        # automatic replace for short operators
2348
        $left = 'title'            if $left =~ '^ti$';
2349
        $left = 'author'           if $left =~ '^au$';
2350
        $left = 'publisher'        if $left =~ '^pb$';
2351
        $left = 'subject'          if $left =~ '^su$';
2352
        $left = 'koha-Auth-Number' if $left =~ '^an$';
2353
        $left = 'keyword'          if $left =~ '^kw$';
2354
        $left = 'itemtype'         if $left =~ '^mc$'; # Fix for Bug 2599 - Search limits not working for NoZebra
2355
        warn "handling leaf... left:$left operator:$operator right:$right" if $DEBUG;
2356
        my $dbh = C4::Context->dbh;
2357
        if ( $operator && $left ne 'keyword' ) {
2358
            #do a specific search
2359
            $operator = 'LIKE' if $operator eq '=' and $right =~ /%/;
2360
            my $sth = $dbh->prepare(
2361
"SELECT biblionumbers,value FROM nozebra WHERE server=? AND indexname=? AND value $operator ?"
2362
            );
2363
            warn "$left / $operator / $right\n" if $DEBUG;
2364
2365
            # split each word, query the DB and build the biblionumbers result
2366
            #sanitizing leftpart
2367
            $left =~ s/^\s+|\s+$//;
2368
            foreach ( split / /, $right ) {
2369
                my $biblionumbers;
2370
                $_ =~ s/^\s+|\s+$//;
2371
                next unless $_;
2372
                warn "EXECUTE : $server, $left, $_" if $DEBUG;
2373
                $sth->execute( $server, $left, $_ )
2374
                  or warn "execute failed: $!";
2375
                while ( my ( $line, $value ) = $sth->fetchrow ) {
2376
2377
# if we are dealing with a numeric value, use only numeric results (in case of >=, <=, > or <)
2378
# otherwise, fill the result
2379
                    $biblionumbers .= $line
2380
                      unless ( $right =~ /^\d+$/ && $value =~ /\D/ );
2381
                    warn "result : $value "
2382
                      . ( $right  =~ /\d/ ) . "=="
2383
                      . ( $value =~ /\D/?$line:"" ) if $DEBUG;         #= $line";
2384
                }
2385
2386
# do a AND with existing list if there is one, otherwise, use the biblionumbers list as 1st result list
2387
                if ($results) {
2388
                    warn "NZAND" if $DEBUG;
2389
                    $results = NZoperatorAND($biblionumbers,$results);
2390
                } else {
2391
                    $results = $biblionumbers;
2392
                }
2393
            }
2394
        }
2395
        else {
2396
      #do a complete search (all indexes), if index='kw' do complete search too.
2397
            my $sth = $dbh->prepare(
2398
"SELECT biblionumbers FROM nozebra WHERE server=? AND value LIKE ?"
2399
            );
2400
2401
            # split each word, query the DB and build the biblionumbers result
2402
            foreach ( split / /, $string ) {
2403
                next if C4::Context->stopwords->{ uc($_) };   # skip if stopword
2404
                warn "search on all indexes on $_" if $DEBUG;
2405
                my $biblionumbers;
2406
                next unless $_;
2407
                $sth->execute( $server, $_ );
2408
                while ( my $line = $sth->fetchrow ) {
2409
                    $biblionumbers .= $line;
2410
                }
2411
2412
# do a AND with existing list if there is one, otherwise, use the biblionumbers list as 1st result list
2413
                if ($results) {
2414
                    $results = NZoperatorAND($biblionumbers,$results);
2415
                }
2416
                else {
2417
                    warn "NEW RES for $_ = $biblionumbers" if $DEBUG;
2418
                    $results = $biblionumbers;
2419
                }
2420
            }
2421
        }
2422
        warn "return : $results for LEAF : $string" if $DEBUG;
2423
        return $results;
2424
    }
2425
    warn "---------\nLeave NZanalyse\n---------" if $DEBUG;
2426
}
2427
2428
sub NZoperatorAND{
2429
    my ($rightresult, $leftresult)=@_;
2430
2431
    my @leftresult = split /;/, $leftresult;
2432
    warn " @leftresult / $rightresult \n" if $DEBUG;
2433
2434
    #             my @rightresult = split /;/,$leftresult;
2435
    my $finalresult;
2436
2437
# parse the left results, and if the biblionumber exist in the right result, save it in finalresult
2438
# the result is stored twice, to have the same weight for AND than OR.
2439
# example : TWO : 61,61,64,121 (two is twice in the biblio #61) / TOWER : 61,64,130
2440
# result : 61,61,61,61,64,64 for two AND tower : 61 has more weight than 64
2441
    foreach (@leftresult) {
2442
        my $value = $_;
2443
        my $countvalue;
2444
        ( $value, $countvalue ) = ( $1, $2 ) if ($value=~/(.*)-(\d+)$/);
2445
        if ( $rightresult =~ /\Q$value\E-(\d+);/ ) {
2446
            $countvalue = ( $1 > $countvalue ? $countvalue : $1 );
2447
            $finalresult .=
2448
                "$value-$countvalue;$value-$countvalue;";
2449
        }
2450
    }
2451
    warn "NZAND DONE : $finalresult \n" if $DEBUG;
2452
    return $finalresult;
2453
}
2454
2455
sub NZoperatorOR{
2456
    my ($rightresult, $leftresult)=@_;
2457
    return $rightresult.$leftresult;
2458
}
2459
2460
sub NZoperatorNOT{
2461
    my ($leftresult, $rightresult)=@_;
2462
2463
    my @leftresult = split /;/, $leftresult;
2464
2465
    #             my @rightresult = split /;/,$leftresult;
2466
    my $finalresult;
2467
    foreach (@leftresult) {
2468
        my $value=$_;
2469
        $value=$1 if $value=~m/(.*)-\d+$/;
2470
        unless ($rightresult =~ "$value-") {
2471
            $finalresult .= "$_;";
2472
        }
2473
    }
2474
    return $finalresult;
2475
}
2476
2477
=head2 NZorder
2478
2479
  $finalresult = NZorder($biblionumbers, $ordering,$results_per_page,$offset);
2480
2481
  TODO :: Description
2482
2483
=cut
2484
2485
sub NZorder {
2486
    my ( $biblionumbers, $ordering, $results_per_page, $offset ) = @_;
2487
    warn "biblionumbers = $biblionumbers and ordering = $ordering\n" if $DEBUG;
2488
2489
    # order title asc by default
2490
    #     $ordering = '1=36 <i' unless $ordering;
2491
    $results_per_page = 20 unless $results_per_page;
2492
    $offset           = 0  unless $offset;
2493
    my $dbh = C4::Context->dbh;
2494
2495
    #
2496
    # order by POPULARITY
2497
    #
2498
    if ( $ordering =~ /popularity/ ) {
2499
        my %result;
2500
        my %popularity;
2501
2502
        # popularity is not in MARC record, it's builded from a specific query
2503
        my $sth =
2504
          $dbh->prepare("select sum(issues) from items where biblionumber=?");
2505
        foreach ( split /;/, $biblionumbers ) {
2506
            my ( $biblionumber, $title ) = split /,/, $_;
2507
            $result{$biblionumber} = GetMarcBiblio($biblionumber);
2508
            $sth->execute($biblionumber);
2509
            my $popularity = $sth->fetchrow || 0;
2510
2511
# hint : the key is popularity.title because we can have
2512
# many results with the same popularity. In this case, sub-ordering is done by title
2513
# we also have biblionumber to avoid bug for 2 biblios with the same title & popularity
2514
# (un-frequent, I agree, but we won't forget anything that way ;-)
2515
            $popularity{ sprintf( "%10d", $popularity ) . $title
2516
                  . $biblionumber } = $biblionumber;
2517
        }
2518
2519
    # sort the hash and return the same structure as GetRecords (Zebra querying)
2520
        my $result_hash;
2521
        my $numbers = 0;
2522
        if ( $ordering eq 'popularity_dsc' ) {    # sort popularity DESC
2523
            foreach my $key ( sort { $b cmp $a } ( keys %popularity ) ) {
2524
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2525
                  $result{ $popularity{$key} }->as_usmarc();
2526
            }
2527
        }
2528
        else {                                    # sort popularity ASC
2529
            foreach my $key ( sort ( keys %popularity ) ) {
2530
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2531
                  $result{ $popularity{$key} }->as_usmarc();
2532
            }
2533
        }
2534
        my $finalresult = ();
2535
        $result_hash->{'hits'}         = $numbers;
2536
        $finalresult->{'biblioserver'} = $result_hash;
2537
        return $finalresult;
2538
2539
        #
2540
        # ORDER BY author
2541
        #
2542
    }
2543
    elsif ( $ordering =~ /author/ ) {
2544
        my %result;
2545
        foreach ( split /;/, $biblionumbers ) {
2546
            my ( $biblionumber, $title ) = split /,/, $_;
2547
            my $record = GetMarcBiblio($biblionumber);
2548
            my $author;
2549
            if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
2550
                $author = $record->subfield( '200', 'f' );
2551
                $author = $record->subfield( '700', 'a' ) unless $author;
2552
            }
2553
            else {
2554
                $author = $record->subfield( '100', 'a' );
2555
            }
2556
2557
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
2558
# and we don't want to get only 1 result for each of them !!!
2559
            $result{ $author . $biblionumber } = $record;
2560
        }
2561
2562
    # sort the hash and return the same structure as GetRecords (Zebra querying)
2563
        my $result_hash;
2564
        my $numbers = 0;
2565
        if ( $ordering eq 'author_za' || $ordering eq 'author_dsc' ) {    # sort by author desc
2566
            foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
2567
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2568
                  $result{$key}->as_usmarc();
2569
            }
2570
        }
2571
        else {                               # sort by author ASC
2572
            foreach my $key ( sort ( keys %result ) ) {
2573
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2574
                  $result{$key}->as_usmarc();
2575
            }
2576
        }
2577
        my $finalresult = ();
2578
        $result_hash->{'hits'}         = $numbers;
2579
        $finalresult->{'biblioserver'} = $result_hash;
2580
        return $finalresult;
2581
2582
        #
2583
        # ORDER BY callnumber
2584
        #
2585
    }
2586
    elsif ( $ordering =~ /callnumber/ ) {
2587
        my %result;
2588
        foreach ( split /;/, $biblionumbers ) {
2589
            my ( $biblionumber, $title ) = split /,/, $_;
2590
            my $record = GetMarcBiblio($biblionumber);
2591
            my $callnumber;
2592
            my $frameworkcode = GetFrameworkCode($biblionumber);
2593
            my ( $callnumber_tag, $callnumber_subfield ) = GetMarcFromKohaField(  'items.itemcallnumber', $frameworkcode);
2594
               ( $callnumber_tag, $callnumber_subfield ) = GetMarcFromKohaField('biblioitems.callnumber', $frameworkcode)
2595
                unless $callnumber_tag;
2596
            if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
2597
                $callnumber = $record->subfield( '200', 'f' );
2598
            } else {
2599
                $callnumber = $record->subfield( '100', 'a' );
2600
            }
2601
2602
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
2603
# and we don't want to get only 1 result for each of them !!!
2604
            $result{ $callnumber . $biblionumber } = $record;
2605
        }
2606
2607
    # sort the hash and return the same structure as GetRecords (Zebra querying)
2608
        my $result_hash;
2609
        my $numbers = 0;
2610
        if ( $ordering eq 'call_number_dsc' ) {    # sort by title desc
2611
            foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
2612
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2613
                  $result{$key}->as_usmarc();
2614
            }
2615
        }
2616
        else {                                     # sort by title ASC
2617
            foreach my $key ( sort { $a cmp $b } ( keys %result ) ) {
2618
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2619
                  $result{$key}->as_usmarc();
2620
            }
2621
        }
2622
        my $finalresult = ();
2623
        $result_hash->{'hits'}         = $numbers;
2624
        $finalresult->{'biblioserver'} = $result_hash;
2625
        return $finalresult;
2626
    }
2627
    elsif ( $ordering =~ /pubdate/ ) {             #pub year
2628
        my %result;
2629
        foreach ( split /;/, $biblionumbers ) {
2630
            my ( $biblionumber, $title ) = split /,/, $_;
2631
            my $record = GetMarcBiblio($biblionumber);
2632
            my ( $publicationyear_tag, $publicationyear_subfield ) =
2633
              GetMarcFromKohaField( 'biblioitems.publicationyear', '' );
2634
            my $publicationyear =
2635
              $record->subfield( $publicationyear_tag,
2636
                $publicationyear_subfield );
2637
2638
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
2639
# and we don't want to get only 1 result for each of them !!!
2640
            $result{ $publicationyear . $biblionumber } = $record;
2641
        }
2642
2643
    # sort the hash and return the same structure as GetRecords (Zebra querying)
2644
        my $result_hash;
2645
        my $numbers = 0;
2646
        if ( $ordering eq 'pubdate_dsc' ) {    # sort by pubyear desc
2647
            foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
2648
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2649
                  $result{$key}->as_usmarc();
2650
            }
2651
        }
2652
        else {                                 # sort by pub year ASC
2653
            foreach my $key ( sort ( keys %result ) ) {
2654
                $result_hash->{'RECORDS'}[ $numbers++ ] =
2655
                  $result{$key}->as_usmarc();
2656
            }
2657
        }
2658
        my $finalresult = ();
2659
        $result_hash->{'hits'}         = $numbers;
2660
        $finalresult->{'biblioserver'} = $result_hash;
2661
        return $finalresult;
2662
2663
        #
2664
        # ORDER BY title
2665
        #
2666
    }
2667
    elsif ( $ordering =~ /title/ ) {
2668
2669
# the title is in the biblionumbers string, so we just need to build a hash, sort it and return
2670
        my %result;
2671
        foreach ( split /;/, $biblionumbers ) {
2672
            my ( $biblionumber, $title ) = split /,/, $_;
2673
2674
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
2675
# and we don't want to get only 1 result for each of them !!!
2676
# hint & speed improvement : we can order without reading the record
2677
# so order, and read records only for the requested page !
2678
            $result{ $title . $biblionumber } = $biblionumber;
2679
        }
2680
2681
    # sort the hash and return the same structure as GetRecords (Zebra querying)
2682
        my $result_hash;
2683
        my $numbers = 0;
2684
        if ( $ordering eq 'title_az' ) {    # sort by title desc
2685
            foreach my $key ( sort ( keys %result ) ) {
2686
                $result_hash->{'RECORDS'}[ $numbers++ ] = $result{$key};
2687
            }
2688
        }
2689
        else {                              # sort by title ASC
2690
            foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
2691
                $result_hash->{'RECORDS'}[ $numbers++ ] = $result{$key};
2692
            }
2693
        }
2694
2695
        # limit the $results_per_page to result size if it's more
2696
        $results_per_page = $numbers - 1 if $numbers < $results_per_page;
2697
2698
        # for the requested page, replace biblionumber by the complete record
2699
        # speed improvement : avoid reading too much things
2700
        for (
2701
            my $counter = $offset ;
2702
            $counter <= $offset + $results_per_page ;
2703
            $counter++
2704
          )
2705
        {
2706
            $result_hash->{'RECORDS'}[$counter] =
2707
              GetMarcBiblio( $result_hash->{'RECORDS'}[$counter] )->as_usmarc;
2708
        }
2709
        my $finalresult = ();
2710
        $result_hash->{'hits'}         = $numbers;
2711
        $finalresult->{'biblioserver'} = $result_hash;
2712
        return $finalresult;
2713
    }
2714
    else {
2715
2716
#
2717
# order by ranking
2718
#
2719
# we need 2 hashes to order by ranking : the 1st one to count the ranking, the 2nd to order by ranking
2720
        my %result;
2721
        my %count_ranking;
2722
        foreach ( split /;/, $biblionumbers ) {
2723
            my ( $biblionumber, $title ) = split /,/, $_;
2724
            $title =~ /(.*)-(\d)/;
2725
2726
            # get weight
2727
            my $ranking = $2;
2728
2729
# note that we + the ranking because ranking is calculated on weight of EACH term requested.
2730
# if we ask for "two towers", and "two" has weight 2 in biblio N, and "towers" has weight 4 in biblio N
2731
# biblio N has ranking = 6
2732
            $count_ranking{$biblionumber} += $ranking;
2733
        }
2734
2735
# build the result by "inverting" the count_ranking hash
2736
# 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
2737
#         warn "counting";
2738
        foreach ( keys %count_ranking ) {
2739
            $result{ sprintf( "%10d", $count_ranking{$_} ) . '-' . $_ } = $_;
2740
        }
2741
2742
    # sort the hash and return the same structure as GetRecords (Zebra querying)
2743
        my $result_hash;
2744
        my $numbers = 0;
2745
        foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
2746
            $result_hash->{'RECORDS'}[ $numbers++ ] = $result{$key};
2747
        }
2748
2749
        # limit the $results_per_page to result size if it's more
2750
        $results_per_page = $numbers - 1 if $numbers < $results_per_page;
2751
2752
        # for the requested page, replace biblionumber by the complete record
2753
        # speed improvement : avoid reading too much things
2754
        for (
2755
            my $counter = $offset ;
2756
            $counter <= $offset + $results_per_page ;
2757
            $counter++
2758
          )
2759
        {
2760
            $result_hash->{'RECORDS'}[$counter] =
2761
              GetMarcBiblio( $result_hash->{'RECORDS'}[$counter] )->as_usmarc
2762
              if $result_hash->{'RECORDS'}[$counter];
2763
        }
2764
        my $finalresult = ();
2765
        $result_hash->{'hits'}         = $numbers;
2766
        $finalresult->{'biblioserver'} = $result_hash;
2767
        return $finalresult;
2768
    }
2769
}
2770
2164
2771
=head2 enabled_staff_search_views
2165
=head2 enabled_staff_search_views
2772
2166
(-)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 390-435 var holdForPatron = function () { Link Here
390
            </form>
390
            </form>
391
        [% ELSE %]
391
        [% ELSE %]
392
392
393
                [% IF ( NoZebra ) %]
394
                <!-- ######### -->
395
                <div id="facets">
396
                <dl>
397
                <!-- FACETS START -->
398
                [% IF ( opacfacets ) %]
399
                    <dt id="facets1" onclick="var Elt=document.getElementById('facets_list');if (Elt.style.display!='block'){Elt.style.display='block';} else {Elt.style.display='none';}">
400
                    Refine your search
401
                    </dt>
402
                    <dd id="facets_list" style="display:none;">
403
                    <ul>
404
                    [% FOREACH facets_loo IN facets_loop %]
405
                    <li id="[% facets_loo.type_id %]">[% facets_loo.type_label %]
406
                        <ul>
407
                        [% FOREACH facet IN facets_loo.facets %]
408
                            <li>
409
                                <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 %]">
410
                                    [% facet.facet_label_value %]
411
                                </a> ([% facet.facet_count %])
412
                            </li>
413
                        [% END %]
414
                        [% IF ( facets_loo.expandable ) %]
415
                            <li class="showmore">
416
                                <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 %]">
417
                                    Show more
418
                                </a>
419
                            </li>
420
                        [% END %]
421
                        </ul>
422
                    </li>
423
                    [% END %]
424
                    </ul>
425
                    </dd>
426
                [% END %]
427
                <!-- FACETS END -->
428
                </dl>
429
            </div>
430
            <!-- ######### -->
431
            <!-- NoZebra -->[% END %]
432
433
            <div id="searchresults">
393
            <div id="searchresults">
434
                <form action="/cgi-bin/koha/catalogue/search.pl" method="get" name="bookbag_form" id="bookbag_form">
394
                <form action="/cgi-bin/koha/catalogue/search.pl" method="get" name="bookbag_form" id="bookbag_form">
435
                [% IF ( searchdesc ) %]
395
                [% 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 489-499 if ($tag) { Link Here
489
    $results_hashref->{biblioserver}->{RECORDS} = \@marclist;
489
    $results_hashref->{biblioserver}->{RECORDS} = \@marclist;
490
    # FIXME: tag search and standard search should work together, not exclusively
490
    # FIXME: tag search and standard search should work together, not exclusively
491
    # FIXME: No facets for tags search.
491
    # FIXME: No facets for tags search.
492
}
493
elsif (C4::Context->preference('NoZebra')) {
494
    eval {
495
        ($error, $results_hashref, $facets) = NZgetRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$query_type,$scan);
496
    };
497
} elsif ($build_grouped_results) {
492
} elsif ($build_grouped_results) {
498
    eval {
493
    eval {
499
        ($error, $results_hashref, $facets) = C4::Search::pazGetRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$query_type,$scan);
494
        ($error, $results_hashref, $facets) = C4::Search::pazGetRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$query_type,$scan);
Lines 668-674 for (my $i=0;$i<@servers;$i++) { Link Here
668
            exit;
663
            exit;
669
        }
664
        }
670
        if ($hits) {
665
        if ($hits) {
671
            if (!C4::Context->preference('NoZebra') && !$build_grouped_results) {
666
            if ( !$build_grouped_results ) {
672
                # We build the encrypted list of first OPACnumSearchResults biblios to pass with the search criteria for paging on opac-detail
667
                # We build the encrypted list of first OPACnumSearchResults biblios to pass with the search criteria for paging on opac-detail
673
                $pasarParams .= '&amp;listBiblios=';
668
                $pasarParams .= '&amp;listBiblios=';
674
                my $j = 0;
669
                my $j = 0;
(-)a/t/db_dependent/Search.t (-3 / +1 lines)
Lines 40-48 $contextmodule->mock('_new_dbh', sub { Link Here
40
    return $dbh });
40
    return $dbh });
41
$contextmodule->mock('preference', sub {
41
$contextmodule->mock('preference', sub {
42
    my ($self, $pref) = @_;
42
    my ($self, $pref) = @_;
43
    if ($pref eq 'NoZebra') {
43
    if ($pref eq 'marcflavour') {
44
        return 0;
45
    } elsif ($pref eq 'marcflavour') {
46
        return 'MARC21';
44
        return 'MARC21';
47
    } elsif ($pref eq 'QueryStemming') {
45
    } elsif ($pref eq 'QueryStemming') {
48
        return $QueryStemming;
46
        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