Merge branch 'bug_7440' into 3.12-master

This commit is contained in:
Jared Camins-Esakov 2013-03-19 21:20:30 -04:00
commit fb8aa63f9d
33 changed files with 343 additions and 2250 deletions

View file

@ -362,7 +362,6 @@ sub get_template_and_user {
suggestion => C4::Context->preference("suggestion"),
virtualshelves => C4::Context->preference("virtualshelves"),
StaffSerialIssueDisplayCount => C4::Context->preference("StaffSerialIssueDisplayCount"),
NoZebra => C4::Context->preference('NoZebra'),
EasyAnalyticalRecords => C4::Context->preference('EasyAnalyticalRecords'),
LocalCoverImages => C4::Context->preference('LocalCoverImages'),
OPACLocalCoverImages => C4::Context->preference('OPACLocalCoverImages'),

View file

@ -109,305 +109,213 @@ sub SearchAuthorities {
my ($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby,$skipmetadata) = @_;
# warn Dumper($tags, $and_or, $excluding, $operator, $value, $offset,$length,$authtypecode,$sortby);
my $dbh=C4::Context->dbh;
if (C4::Context->preference('NoZebra')) {
#
# build the query
#
my $query;
my $query;
my $qpquery = '';
my $QParser;
$QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser'));
my $attr = '';
# the marclist may contain "mainentry". In this case, search the tag_to_report, that depends on
# the authtypecode. Then, search on $a of this tag_to_report
# also store main entry MARC tag, to extract it at end of search
my $mainentrytag;
##first set the authtype search and may be multiple authorities
if ($authtypecode) {
my $n=0;
my @authtypecode;
my @auths=split / /,$authtypecode ;
foreach my $auth (@auths){
$query .="AND auth_type= $auth ";
$query .=" \@attr 1=authtype \@attr 5=100 ".$auth; ##No truncation on authtype
push @authtypecode ,$auth;
$n++;
}
$query =~ s/^AND //;
my $dosearch;
for(my $i = 0 ; $i <= $#{$value} ; $i++)
{
if (@$value[$i]){
if (@$tags[$i] =~/mainentry|mainmainentry/) {
$query .= qq( AND @$tags[$i] );
} else {
$query .=" AND ";
}
if (@$operator[$i] eq 'is') {
$query.=(@$tags[$i]?"=":""). '"'.@$value[$i].'"';
}elsif (@$operator[$i] eq "="){
$query.=(@$tags[$i]?"=":""). '"'.@$value[$i].'"';
}elsif (@$operator[$i] eq "start"){
$query.=(@$tags[$i]?"=":"").'"'.@$value[$i].'%"';
} else {
$query.=(@$tags[$i]?"=":"").'"'.@$value[$i].'%"';
}
$dosearch=1;
}#if value
}
#
# do the query (if we had some search term
#
if ($dosearch) {
# warn "QUERY : $query";
my $result = C4::Search::NZanalyse($query,'authorityserver');
# warn "result : $result";
my %result;
foreach (split /;/,$result) {
my ($authid,$title) = split /,/,$_;
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
# and we don't want to get only 1 result for each of them !!!
# hint & speed improvement : we can order without reading the record
# so order, and read records only for the requested page !
$result{$title.$authid}=$authid;
}
# sort the hash and return the same structure as GetRecords (Zebra querying)
my @listresult = ();
my $numbers=0;
if ($sortby eq 'HeadingDsc') { # sort by mainmainentry desc
foreach my $key (sort {$b cmp $a} (keys %result)) {
push @listresult, $result{$key};
# warn "push..."$#finalresult;
$numbers++;
}
} else { # sort by mainmainentry ASC
foreach my $key (sort (keys %result)) {
push @listresult, $result{$key};
# warn "push..."$#finalresult;
$numbers++;
}
}
# limit the $results_per_page to result size if it's more
$length = $numbers-$offset if $numbers < ($offset+$length);
# for the requested page, replace authid by the complete record
# speed improvement : avoid reading too much things
my @finalresult;
for (my $counter=$offset;$counter<=$offset+$length-1;$counter++) {
# $finalresult[$counter] = GetAuthority($finalresult[$counter])->as_usmarc;
my $separator=C4::Context->preference('authoritysep');
my $authrecord =GetAuthority($listresult[$counter]);
my $authid=$listresult[$counter];
my $summary=BuildSummary($authrecord,$authid,$authtypecode);
my $query_auth_tag = "SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?";
my $sth = $dbh->prepare($query_auth_tag);
$sth->execute($authtypecode);
my $auth_tag_to_report = $sth->fetchrow;
my %newline;
$newline{used}=CountUsage($authid);
$newline{summary} = $summary;
$newline{authid} = $authid;
$newline{even} = $counter % 2;
push @finalresult, \%newline;
}
return (\@finalresult, $numbers);
} else {
return;
}
} else {
my $query;
my $qpquery = '';
my $QParser;
$QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser'));
my $attr = '';
# the marclist may contain "mainentry". In this case, search the tag_to_report, that depends on
# the authtypecode. Then, search on $a of this tag_to_report
# also store main entry MARC tag, to extract it at end of search
my $mainentrytag;
##first set the authtype search and may be multiple authorities
if ($authtypecode) {
my $n=0;
my @authtypecode;
my @auths=split / /,$authtypecode ;
foreach my $auth (@auths){
$query .=" \@attr 1=authtype \@attr 5=100 ".$auth; ##No truncation on authtype
push @authtypecode ,$auth;
$n++;
}
if ($n>1){
while ($n>1){$query= "\@or ".$query;$n--;}
}
if ($QParser) {
$qpquery .= '(authtype:' . join('|| authtype:', @auths) . ')';
}
}
my $dosearch;
my $and=" \@and " ;
my $q2;
my $attr_cnt = 0;
for(my $i = 0 ; $i <= $#{$value} ; $i++)
{
if (@$value[$i]){
if ( @$tags[$i] eq "mainmainentry" ) {
$attr = " \@attr 1=Heading-Main ";
}
elsif ( @$tags[$i] eq "mainentry" ) {
$attr = " \@attr 1=Heading ";
}
elsif ( @$tags[$i] eq "match" ) {
$attr = " \@attr 1=Match ";
}
elsif ( @$tags[$i] eq "match-heading" ) {
$attr = " \@attr 1=Match-heading ";
}
elsif ( @$tags[$i] eq "see-from" ) {
$attr = " \@attr 1=Match-heading-see-from ";
}
elsif ( @$tags[$i] eq "thesaurus" ) {
$attr = " \@attr 1=Subject-heading-thesaurus ";
}
else { # Assume any if no index was specified
$attr = " \@attr 1=Any ";
}
if ( @$operator[$i] eq 'is' ) {
$attr .= " \@attr 4=1 \@attr 5=100 "
; ##Phrase, No truncation,all of subfield field must match
}
elsif ( @$operator[$i] eq "=" ) {
$attr .= " \@attr 4=107 "; #Number Exact match
}
elsif ( @$operator[$i] eq "start" ) {
$attr .= " \@attr 3=2 \@attr 4=1 \@attr 5=1 "
; #Firstinfield Phrase, Right truncated
}
elsif ( @$operator[$i] eq "exact" ) {
$attr .= " \@attr 4=1 \@attr 5=100 \@attr 6=3 "
; ##Phrase, No truncation,all of subfield field must match
}
else {
$attr .= " \@attr 5=1 \@attr 4=6 "
; ## Word list, right truncated, anywhere
if ($sortby eq 'Relevance') {
$attr .= "\@attr 2=102 ";
}
}
@$value[$i] =~ s/"/\\"/g; # Escape the double-quotes in the search value
$attr =$attr."\"".@$value[$i]."\"";
$q2 .=$attr;
$dosearch=1;
++$attr_cnt;
if ($QParser) {
$qpquery .= " $tags->[$i]:\"$value->[$i]\"";
}
}#if value
}
##Add how many queries generated
if (defined $query && $query=~/\S+/){
$query= $and x $attr_cnt . $query . (defined $q2 ? $q2 : '');
} else {
$query= $q2;
}
## Adding order
#$query=' @or @attr 7=2 @attr 1=Heading 0 @or @attr 7=1 @attr 1=Heading 1'.$query if ($sortby eq "HeadingDsc");
my $orderstring;
if ($sortby eq 'HeadingAsc') {
$orderstring = '@attr 7=1 @attr 1=Heading 0';
} elsif ($sortby eq 'HeadingDsc') {
$orderstring = '@attr 7=2 @attr 1=Heading 0';
} elsif ($sortby eq 'AuthidAsc') {
$orderstring = '@attr 7=1 @attr 4=109 @attr 1=Local-Number 0';
} elsif ($sortby eq 'AuthidDsc') {
$orderstring = '@attr 7=2 @attr 4=109 @attr 1=Local-Number 0';
if ($n>1){
while ($n>1){$query= "\@or ".$query;$n--;}
}
if ($QParser) {
$qpquery .= ' all:all' unless $value->[0];
if ( $value->[0] =~ m/^qp=(.*)$/ ) {
$qpquery = $1;
}
$qpquery .= " #$sortby";
$QParser->parse( $qpquery );
$query = $QParser->target_syntax('authorityserver');
} else {
$query=($query?$query:"\@attr 1=_ALLRECORDS \@attr 2=103 ''");
$query="\@or $orderstring $query" if $orderstring;
$qpquery .= '(authtype:' . join('|| authtype:', @auths) . ')';
}
$offset=0 unless $offset;
my $counter = $offset;
$length=10 unless $length;
my @oAuth;
my $i;
$oAuth[0]=C4::Context->Zconn("authorityserver" , 1);
my $Anewq= new ZOOM::Query::PQF($query,$oAuth[0]);
my $oAResult;
$oAResult= $oAuth[0]->search($Anewq) ;
while (($i = ZOOM::event(\@oAuth)) != 0) {
my $ev = $oAuth[$i-1]->last_event();
last if $ev == ZOOM::Event::ZEND;
}
my($error, $errmsg, $addinfo, $diagset) = $oAuth[0]->error_x();
if ($error) {
warn "oAuth error: $errmsg ($error) $addinfo $diagset\n";
goto NOLUCK;
}
my $nbresults;
$nbresults=$oAResult->size();
my $nremains=$nbresults;
my @result = ();
my @finalresult = ();
if ($nbresults>0){
##Find authid and linkid fields
##we may be searching multiple authoritytypes.
## FIXME this assumes that all authid and linkid fields are the same for all authority types
# my ($authidfield,$authidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.authid",$authtypecode[0]);
# my ($linkidfield,$linkidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.linkid",$authtypecode[0]);
while (($counter < $nbresults) && ($counter < ($offset + $length))) {
##Here we have to extract MARC record and $authid from ZEBRA AUTHORITIES
my $rec=$oAResult->record($counter);
my $marcdata=$rec->raw();
my $authrecord;
my $separator=C4::Context->preference('authoritysep');
$authrecord = MARC::File::USMARC::decode($marcdata);
my $authid=$authrecord->field('001')->data();
my %newline;
$newline{authid} = $authid;
if ( !$skipmetadata ) {
my $summary =
BuildSummary( $authrecord, $authid, $authtypecode );
my $query_auth_tag =
"SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?";
my $sth = $dbh->prepare($query_auth_tag);
$sth->execute($authtypecode);
my $auth_tag_to_report = $sth->fetchrow;
my $reported_tag;
my $mainentry = $authrecord->field($auth_tag_to_report);
if ($mainentry) {
foreach ( $mainentry->subfields() ) {
$reported_tag .= '$' . $_->[0] . $_->[1];
}
}
my $thisauthtype = GetAuthType(GetAuthTypeCode($authid));
unless (defined $thisauthtype) {
$thisauthtype = GetAuthType($authtypecode) if $authtypecode;
}
$newline{authtype} = defined($thisauthtype) ?
$thisauthtype->{'authtypetext'} : '';
$newline{summary} = $summary;
$newline{even} = $counter % 2;
$newline{reported_tag} = $reported_tag;
}
$counter++;
push @finalresult, \%newline;
}## while counter
###
if (! $skipmetadata) {
for (my $z=0; $z<@finalresult; $z++){
my $count=CountUsage($finalresult[$z]{authid});
$finalresult[$z]{used}=$count;
}# all $z's
}
}## if nbresult
NOLUCK:
$oAResult->destroy();
# $oAuth[0]->destroy();
return (\@finalresult, $nbresults);
}
my $dosearch;
my $and=" \@and " ;
my $q2;
my $attr_cnt = 0;
for(my $i = 0 ; $i <= $#{$value} ; $i++)
{
if (@$value[$i]){
if ( @$tags[$i] eq "mainmainentry" ) {
$attr = " \@attr 1=Heading-Main ";
}
elsif ( @$tags[$i] eq "mainentry" ) {
$attr = " \@attr 1=Heading ";
}
elsif ( @$tags[$i] eq "match" ) {
$attr = " \@attr 1=Match ";
}
elsif ( @$tags[$i] eq "match-heading" ) {
$attr = " \@attr 1=Match-heading ";
}
elsif ( @$tags[$i] eq "see-from" ) {
$attr = " \@attr 1=Match-heading-see-from ";
}
elsif ( @$tags[$i] eq "thesaurus" ) {
$attr = " \@attr 1=Subject-heading-thesaurus ";
}
else { # Assume any if no index was specified
$attr = " \@attr 1=Any ";
}
if ( @$operator[$i] eq 'is' ) {
$attr .= " \@attr 4=1 \@attr 5=100 "
; ##Phrase, No truncation,all of subfield field must match
}
elsif ( @$operator[$i] eq "=" ) {
$attr .= " \@attr 4=107 "; #Number Exact match
}
elsif ( @$operator[$i] eq "start" ) {
$attr .= " \@attr 3=2 \@attr 4=1 \@attr 5=1 "
; #Firstinfield Phrase, Right truncated
}
elsif ( @$operator[$i] eq "exact" ) {
$attr .= " \@attr 4=1 \@attr 5=100 \@attr 6=3 "
; ##Phrase, No truncation,all of subfield field must match
}
else {
$attr .= " \@attr 5=1 \@attr 4=6 "
; ## Word list, right truncated, anywhere
if ($sortby eq 'Relevance') {
$attr .= "\@attr 2=102 ";
}
}
@$value[$i] =~ s/"/\\"/g; # Escape the double-quotes in the search value
$attr =$attr."\"".@$value[$i]."\"";
$q2 .=$attr;
$dosearch=1;
++$attr_cnt;
if ($QParser) {
$qpquery .= " $tags->[$i]:\"$value->[$i]\"";
}
}#if value
}
##Add how many queries generated
if (defined $query && $query=~/\S+/){
$query= $and x $attr_cnt . $query . (defined $q2 ? $q2 : '');
} else {
$query= $q2;
}
## Adding order
#$query=' @or @attr 7=2 @attr 1=Heading 0 @or @attr 7=1 @attr 1=Heading 1'.$query if ($sortby eq "HeadingDsc");
my $orderstring;
if ($sortby eq 'HeadingAsc') {
$orderstring = '@attr 7=1 @attr 1=Heading 0';
} elsif ($sortby eq 'HeadingDsc') {
$orderstring = '@attr 7=2 @attr 1=Heading 0';
} elsif ($sortby eq 'AuthidAsc') {
$orderstring = '@attr 7=1 @attr 4=109 @attr 1=Local-Number 0';
} elsif ($sortby eq 'AuthidDsc') {
$orderstring = '@attr 7=2 @attr 4=109 @attr 1=Local-Number 0';
}
if ($QParser) {
$qpquery .= ' all:all' unless $value->[0];
if ( $value->[0] =~ m/^qp=(.*)$/ ) {
$qpquery = $1;
}
$qpquery .= " #$sortby";
$QParser->parse( $qpquery );
$query = $QParser->target_syntax('authorityserver');
} else {
$query=($query?$query:"\@attr 1=_ALLRECORDS \@attr 2=103 ''");
$query="\@or $orderstring $query" if $orderstring;
}
$offset=0 unless $offset;
my $counter = $offset;
$length=10 unless $length;
my @oAuth;
my $i;
$oAuth[0]=C4::Context->Zconn("authorityserver" , 1);
my $Anewq= new ZOOM::Query::PQF($query,$oAuth[0]);
my $oAResult;
$oAResult= $oAuth[0]->search($Anewq) ;
while (($i = ZOOM::event(\@oAuth)) != 0) {
my $ev = $oAuth[$i-1]->last_event();
last if $ev == ZOOM::Event::ZEND;
}
my($error, $errmsg, $addinfo, $diagset) = $oAuth[0]->error_x();
if ($error) {
warn "oAuth error: $errmsg ($error) $addinfo $diagset\n";
goto NOLUCK;
}
my $nbresults;
$nbresults=$oAResult->size();
my $nremains=$nbresults;
my @result = ();
my @finalresult = ();
if ($nbresults>0){
##Find authid and linkid fields
##we may be searching multiple authoritytypes.
## FIXME this assumes that all authid and linkid fields are the same for all authority types
# my ($authidfield,$authidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.authid",$authtypecode[0]);
# my ($linkidfield,$linkidsubfield)=GetAuthMARCFromKohaField($dbh,"auth_header.linkid",$authtypecode[0]);
while (($counter < $nbresults) && ($counter < ($offset + $length))) {
##Here we have to extract MARC record and $authid from ZEBRA AUTHORITIES
my $rec=$oAResult->record($counter);
my $marcdata=$rec->raw();
my $authrecord;
my $separator=C4::Context->preference('authoritysep');
$authrecord = MARC::File::USMARC::decode($marcdata);
my $authid=$authrecord->field('001')->data();
my %newline;
$newline{authid} = $authid;
if ( !$skipmetadata ) {
my $summary =
BuildSummary( $authrecord, $authid, $authtypecode );
my $query_auth_tag =
"SELECT auth_tag_to_report FROM auth_types WHERE authtypecode=?";
my $sth = $dbh->prepare($query_auth_tag);
$sth->execute($authtypecode);
my $auth_tag_to_report = $sth->fetchrow;
my $reported_tag;
my $mainentry = $authrecord->field($auth_tag_to_report);
if ($mainentry) {
foreach ( $mainentry->subfields() ) {
$reported_tag .= '$' . $_->[0] . $_->[1];
}
}
my $thisauthtype = GetAuthType(GetAuthTypeCode($authid));
unless (defined $thisauthtype) {
$thisauthtype = GetAuthType($authtypecode) if $authtypecode;
}
$newline{authtype} = defined($thisauthtype) ?
$thisauthtype->{'authtypetext'} : '';
$newline{summary} = $summary;
$newline{even} = $counter % 2;
$newline{reported_tag} = $reported_tag;
}
$counter++;
push @finalresult, \%newline;
}## while counter
###
if (! $skipmetadata) {
for (my $z=0; $z<@finalresult; $z++){
my $count=CountUsage($finalresult[$z]{authid});
$finalresult[$z]{used}=$count;
}# all $z's
}
}## if nbresult
NOLUCK:
$oAResult->destroy();
# $oAuth[0]->destroy();
return (\@finalresult, $nbresults);
}
=head2 CountUsage
@ -420,12 +328,6 @@ counts Usage of Authid in bibliorecords.
sub CountUsage {
my ($authid) = @_;
if (C4::Context->preference('NoZebra')) {
# Read the index Koha-Auth-Number for this authid and count the lines
my $result = C4::Search::NZanalyse("an=$authid");
my @tab = split /;/,$result;
return scalar @tab;
} else {
### ZOOM search here
my $query;
$query= "an:".$authid;
@ -436,7 +338,6 @@ sub CountUsage {
}
return $result;
}
}
=head2 CountUsageChildren
@ -1505,46 +1406,30 @@ sub merge {
my @reccache;
# search all biblio tags using this authority.
#Getting marcbiblios impacted by the change.
if (C4::Context->preference('NoZebra')) {
#nozebra way
my $dbh=C4::Context->dbh;
my $rq=$dbh->prepare(qq(SELECT biblionumbers from nozebra where indexname="an" and server="biblioserver" and value="$mergefrom" ));
$rq->execute;
while (my $biblionumbers=$rq->fetchrow){
my @biblionumbers=split /;/,$biblionumbers;
foreach (@biblionumbers) {
if ($_=~/(\d+),.*/) {
my $marc=GetMarcBiblio($1);
push @reccache,$marc;
}
}
}
} else {
#zebra connection
my $oConnection=C4::Context->Zconn("biblioserver",0);
# We used to use XML syntax here, but that no longer works.
# Thankfully, we don't need it.
my $query;
$query= "an=".$mergefrom;
my $oResult = $oConnection->search(new ZOOM::Query::CCL2RPN( $query, $oConnection ));
my $count = 0;
if ($oResult) {
$count=$oResult->size();
}
my $z=0;
while ( $z<$count ) {
my $rec;
$rec=$oResult->record($z);
my $marcdata = $rec->raw();
my $marcrecordzebra= MARC::Record->new_from_usmarc($marcdata);
my ( $biblionumbertagfield, $biblionumbertagsubfield ) = &GetMarcFromKohaField( "biblio.biblionumber", '' );
my $i = ($biblionumbertagfield < 10) ? $marcrecordzebra->field($biblionumbertagfield)->data : $marcrecordzebra->subfield($biblionumbertagfield, $biblionumbertagsubfield);
my $marcrecorddb=GetMarcBiblio($i);
push @reccache, $marcrecorddb;
$z++;
}
$oResult->destroy();
#zebra connection
my $oConnection=C4::Context->Zconn("biblioserver",0);
# We used to use XML syntax here, but that no longer works.
# Thankfully, we don't need it.
my $query;
$query= "an=".$mergefrom;
my $oResult = $oConnection->search(new ZOOM::Query::CCL2RPN( $query, $oConnection ));
my $count = 0;
if ($oResult) {
$count=$oResult->size();
}
my $z=0;
while ( $z<$count ) {
my $rec;
$rec=$oResult->record($z);
my $marcdata = $rec->raw();
my $marcrecordzebra= MARC::Record->new_from_usmarc($marcdata);
my ( $biblionumbertagfield, $biblionumbertagsubfield ) = &GetMarcFromKohaField( "biblio.biblionumber", '' );
my $i = ($biblionumbertagfield < 10) ? $marcrecordzebra->field($biblionumbertagfield)->data : $marcrecordzebra->subfield($biblionumbertagfield, $biblionumbertagsubfield);
my $marcrecorddb=GetMarcBiblio($i);
push @reccache, $marcrecorddb;
$z++;
}
$oResult->destroy();
#warn scalar(@reccache)." biblios to update";
# Get All candidate Tags for the change
# (This will reduce the search scope in marc records).

View file

@ -136,7 +136,6 @@ BEGIN {
&TransformHtmlToMarc2
&TransformHtmlToMarc
&TransformHtmlToXml
&GetNoZebraIndexes
prepare_host_field
);
}
@ -444,17 +443,9 @@ sub DelBiblio {
# Delete in Zebra. Be careful NOT to move this line after _koha_delete_biblio
# for at least 2 reasons :
# - we need to read the biblio if NoZebra is set (to remove it from the indexes
# - if something goes wrong, the biblio may be deleted from Koha but not from zebra
# 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)
my $oldRecord;
if ( C4::Context->preference("NoZebra") ) {
# only NoZebra indexing needs to have
# the previous version of the record
$oldRecord = GetMarcBiblio($biblionumber);
}
ModZebra( $biblionumber, "recordDelete", "biblioserver", $oldRecord, undef );
ModZebra( $biblionumber, "recordDelete", "biblioserver" );
# delete biblioitems and items from Koha tables and save in deletedbiblioitems,deleteditems
$sth = $dbh->prepare("SELECT biblioitemnumber FROM biblioitems WHERE biblionumber=?");
@ -2760,7 +2751,7 @@ sub TransformMarcToKohaOneField {
=head2 ModZebra
ModZebra( $biblionumber, $op, $server, $oldRecord, $newRecord );
ModZebra( $biblionumber, $op, $server );
$biblionumber is the biblionumber we want to index
@ -2768,99 +2759,34 @@ $op is specialUpdate or delete, and is used to know what we want to do
$server is the server that we want to update
$oldRecord is the MARC::Record containing the previous version of the record. This is used only when
NoZebra=1, as NoZebra indexing needs to know the previous version of a record in order to
do an update.
$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.
=cut
sub ModZebra {
###Accepts a $server variable thus we can use it for biblios authorities or other zebra dbs
my ( $biblionumber, $op, $server, $oldRecord, $newRecord ) = @_;
my ( $biblionumber, $op, $server ) = @_;
my $dbh = C4::Context->dbh;
# true ModZebra commented until indexdata fixes zebraDB crashes (it seems they occur on multiple updates
# at the same time
# replaced by a zebraqueue table, that is filled with ModZebra to run.
# the table is emptied by misc/cronjobs/zebraqueue_start.pl script
# the table is emptied by rebuild_zebra.pl script (using the -z switch)
if ( C4::Context->preference("NoZebra") ) {
# lock the nozebra table : we will read index lines, update them in Perl process
# and write everything in 1 transaction.
# lock the table to avoid someone else overwriting what we are doing
$dbh->do('LOCK TABLES nozebra WRITE,biblio WRITE,biblioitems WRITE, systempreferences WRITE, auth_types WRITE, auth_header WRITE, auth_subfield_structure READ');
my %result; # the result hash that will be built by deletion / add, and written on mySQL at the end, to improve speed
if ( $op eq 'specialUpdate' ) {
# OK, we have to add or update the record
# 1st delete (virtually, in indexes), if record actually exists
if ($oldRecord) {
%result = _DelBiblioNoZebra( $biblionumber, $oldRecord, $server );
}
# ... add the record
%result = _AddBiblioNoZebra( $biblionumber, $newRecord, $server, %result );
} else {
# it's a deletion, delete the record...
# warn "DELETE the record $biblionumber on $server".$record->as_formatted;
%result = _DelBiblioNoZebra( $biblionumber, $oldRecord, $server );
}
# ok, now update the database...
my $sth = $dbh->prepare("UPDATE nozebra SET biblionumbers=? WHERE server=? AND indexname=? AND value=?");
foreach my $key ( keys %result ) {
foreach my $index ( keys %{ $result{$key} } ) {
$sth->execute( $result{$key}->{$index}, $server, $key, $index );
}
}
$dbh->do('UNLOCK TABLES');
} else {
#
# we use zebra, just fill zebraqueue table
#
my $check_sql = "SELECT COUNT(*) FROM zebraqueue
WHERE server = ?
AND biblio_auth_number = ?
AND operation = ?
AND done = 0";
my $check_sth = $dbh->prepare_cached($check_sql);
$check_sth->execute( $server, $biblionumber, $op );
my ($count) = $check_sth->fetchrow_array;
$check_sth->finish();
if ( $count == 0 ) {
my $sth = $dbh->prepare("INSERT INTO zebraqueue (biblio_auth_number,server,operation) VALUES(?,?,?)");
$sth->execute( $biblionumber, $server, $op );
$sth->finish;
}
my $check_sql = "SELECT COUNT(*) FROM zebraqueue
WHERE server = ?
AND biblio_auth_number = ?
AND operation = ?
AND done = 0";
my $check_sth = $dbh->prepare_cached($check_sql);
$check_sth->execute( $server, $biblionumber, $op );
my ($count) = $check_sth->fetchrow_array;
$check_sth->finish();
if ( $count == 0 ) {
my $sth = $dbh->prepare("INSERT INTO zebraqueue (biblio_auth_number,server,operation) VALUES(?,?,?)");
$sth->execute( $biblionumber, $server, $op );
$sth->finish;
}
}
=head2 GetNoZebraIndexes
%indexes = GetNoZebraIndexes;
return the data from NoZebraIndexes syspref.
=cut
sub GetNoZebraIndexes {
my $no_zebra_indexes = C4::Context->preference('NoZebraIndexes');
my %indexes;
INDEX: foreach my $line ( split /['"],[\n\r]*/, $no_zebra_indexes ) {
$line =~ /(.*)=>(.*)/;
my $index = $1; # initial ' or " is removed afterwards
my $fields = $2;
$index =~ s/'|"|\s//g;
$fields =~ s/'|"|\s//g;
$indexes{$index} = $fields;
}
return %indexes;
}
=head2 EmbedItemsInMarcBiblio
@ -2899,268 +2825,6 @@ sub EmbedItemsInMarcBiblio {
=head1 INTERNAL FUNCTIONS
=head2 _DelBiblioNoZebra($biblionumber,$record,$server);
function to delete a biblio in NoZebra indexes
This function does NOT delete anything in database : it reads all the indexes entries
that have to be deleted & delete them in the hash
The SQL part is done either :
- after the Add if we are modifying a biblio (delete + add again)
- immediatly after this sub if we are doing a true deletion.
$server can be 'biblioserver' or 'authorityserver' : it indexes biblios or authorities (in the same table, $server being part of the table itself
=cut
sub _DelBiblioNoZebra {
my ( $biblionumber, $record, $server ) = @_;
# Get the indexes
my $dbh = C4::Context->dbh;
# Get the indexes
my %index;
my $title;
if ( $server eq 'biblioserver' ) {
%index = GetNoZebraIndexes;
# get title of the record (to store the 10 first letters with the index)
my ( $titletag, $titlesubfield ) = GetMarcFromKohaField( 'biblio.title', '' ); # FIXME: should be GetFrameworkCode($biblionumber) ??
$title = lc( $record->subfield( $titletag, $titlesubfield ) );
} else {
# for authorities, the "title" is the $a mainentry
my ( $auth_type_tag, $auth_type_sf ) = C4::AuthoritiesMarc::get_auth_type_location();
my $authref = C4::AuthoritiesMarc::GetAuthType( $record->subfield( $auth_type_tag, $auth_type_sf ) );
warn "ERROR : authtype undefined for " . $record->as_formatted unless $authref;
$title = $record->subfield( $authref->{auth_tag_to_report}, 'a' );
$index{'mainmainentry'} = $authref->{'auth_tag_to_report'} . 'a';
$index{'mainentry'} = $authref->{'auth_tag_to_report'} . '*';
$index{'auth_type'} = "${auth_type_tag}${auth_type_sf}";
}
my %result;
# remove blancks comma (that could cause problem when decoding the string for CQL retrieval) and regexp specific values
$title =~ s/ |,|;|\[|\]|\(|\)|\*|-|'|=//g;
# limit to 10 char, should be enough, and limit the DB size
$title = substr( $title, 0, 10 );
#parse each field
my $sth2 = $dbh->prepare('SELECT biblionumbers FROM nozebra WHERE server=? AND indexname=? AND value=?');
foreach my $field ( $record->fields() ) {
#parse each subfield
next if $field->tag < 10;
foreach my $subfield ( $field->subfields() ) {
my $tag = $field->tag();
my $subfieldcode = $subfield->[0];
my $indexed = 0;
# check each index to see if the subfield is stored somewhere
# otherwise, store it in __RAW__ index
foreach my $key ( keys %index ) {
# warn "examining $key index : ".$index{$key}." for $tag $subfieldcode";
if ( $index{$key} =~ /$tag\*/ or $index{$key} =~ /$tag$subfieldcode/ ) {
$indexed = 1;
my $line = lc $subfield->[1];
# remove meaningless value in the field...
$line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:/ /g;
# ... and split in words
foreach ( split / /, $line ) {
next unless $_; # skip empty values (multiple spaces)
# if the entry is already here, do nothing, the biblionumber has already be removed
unless ( defined( $result{$key}->{$_} ) && ( $result{$key}->{$_} =~ /$biblionumber,$title\-(\d);/ ) ) {
# get the index value if it exist in the nozebra table and remove the entry, otherwise, do nothing
$sth2->execute( $server, $key, $_ );
my $existing_biblionumbers = $sth2->fetchrow;
# it exists
if ($existing_biblionumbers) {
# warn " existing for $key $_: $existing_biblionumbers";
$result{$key}->{$_} = $existing_biblionumbers;
$result{$key}->{$_} =~ s/$biblionumber,$title\-(\d);//;
}
}
}
}
}
# the subfield is not indexed, store it in __RAW__ index anyway
unless ($indexed) {
my $line = lc $subfield->[1];
$line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:/ /g;
# ... and split in words
foreach ( split / /, $line ) {
next unless $_; # skip empty values (multiple spaces)
# if the entry is already here, do nothing, the biblionumber has already be removed
unless ( $result{'__RAW__'}->{$_} =~ /$biblionumber,$title\-(\d);/ ) {
# get the index value if it exist in the nozebra table and remove the entry, otherwise, do nothing
$sth2->execute( $server, '__RAW__', $_ );
my $existing_biblionumbers = $sth2->fetchrow;
# it exists
if ($existing_biblionumbers) {
$result{'__RAW__'}->{$_} = $existing_biblionumbers;
$result{'__RAW__'}->{$_} =~ s/$biblionumber,$title\-(\d);//;
}
}
}
}
}
}
return %result;
}
=head2 _AddBiblioNoZebra
_AddBiblioNoZebra($biblionumber, $record, $server, %result);
function to add a biblio in NoZebra indexes
=cut
sub _AddBiblioNoZebra {
my ( $biblionumber, $record, $server, %result ) = @_;
my $dbh = C4::Context->dbh;
# Get the indexes
my %index;
my $title;
if ( $server eq 'biblioserver' ) {
%index = GetNoZebraIndexes;
# get title of the record (to store the 10 first letters with the index)
my ( $titletag, $titlesubfield ) = GetMarcFromKohaField( 'biblio.title', '' ); # FIXME: should be GetFrameworkCode($biblionumber) ??
$title = lc( $record->subfield( $titletag, $titlesubfield ) );
} else {
# warn "server : $server";
# for authorities, the "title" is the $a mainentry
my ( $auth_type_tag, $auth_type_sf ) = C4::AuthoritiesMarc::get_auth_type_location();
my $authref = C4::AuthoritiesMarc::GetAuthType( $record->subfield( $auth_type_tag, $auth_type_sf ) );
warn "ERROR : authtype undefined for " . $record->as_formatted unless $authref;
$title = $record->subfield( $authref->{auth_tag_to_report}, 'a' );
$index{'mainmainentry'} = $authref->{auth_tag_to_report} . 'a';
$index{'mainentry'} = $authref->{auth_tag_to_report} . '*';
$index{'auth_type'} = "${auth_type_tag}${auth_type_sf}";
}
# remove blancks comma (that could cause problem when decoding the string for CQL retrieval) and regexp specific values
$title =~ s/ |\.|,|;|\[|\]|\(|\)|\*|-|'|:|=|\r|\n//g;
# limit to 10 char, should be enough, and limit the DB size
$title = substr( $title, 0, 10 );
#parse each field
my $sth2 = $dbh->prepare('SELECT biblionumbers FROM nozebra WHERE server=? AND indexname=? AND value=?');
foreach my $field ( $record->fields() ) {
#parse each subfield
###FIXME: impossible to index a 001-009 value with NoZebra
next if $field->tag < 10;
foreach my $subfield ( $field->subfields() ) {
my $tag = $field->tag();
my $subfieldcode = $subfield->[0];
my $indexed = 0;
# warn "INDEXING :".$subfield->[1];
# check each index to see if the subfield is stored somewhere
# otherwise, store it in __RAW__ index
foreach my $key ( keys %index ) {
# warn "examining $key index : ".$index{$key}." for $tag $subfieldcode";
if ( $index{$key} =~ /$tag\*/ or $index{$key} =~ /$tag$subfieldcode/ ) {
$indexed = 1;
my $line = lc $subfield->[1];
# remove meaningless value in the field...
$line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:|\r|\n/ /g;
# ... and split in words
foreach ( split / /, $line ) {
next unless $_; # skip empty values (multiple spaces)
# if the entry is already here, improve weight
# warn "managing $_";
if ( exists $result{$key}->{$_} && $result{$key}->{"$_"} =~ /$biblionumber,\Q$title\E\-(\d+);/ ) {
my $weight = $1 + 1;
$result{$key}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//g;
$result{$key}->{"$_"} .= "$biblionumber,$title-$weight;";
} else {
# get the value if it exist in the nozebra table, otherwise, create it
$sth2->execute( $server, $key, $_ );
my $existing_biblionumbers = $sth2->fetchrow;
# it exists
if ($existing_biblionumbers) {
$result{$key}->{"$_"} = $existing_biblionumbers;
my $weight = defined $1 ? $1 + 1 : 1;
$result{$key}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//g;
$result{$key}->{"$_"} .= "$biblionumber,$title-$weight;";
# create a new ligne for this entry
} else {
# warn "INSERT : $server / $key / $_";
$dbh->do( 'INSERT INTO nozebra SET server=' . $dbh->quote($server) . ', indexname=' . $dbh->quote($key) . ',value=' . $dbh->quote($_) );
$result{$key}->{"$_"} .= "$biblionumber,$title-1;";
}
}
}
}
}
# the subfield is not indexed, store it in __RAW__ index anyway
unless ($indexed) {
my $line = lc $subfield->[1];
$line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:|\r|\n/ /g;
# ... and split in words
foreach ( split / /, $line ) {
next unless $_; # skip empty values (multiple spaces)
# if the entry is already here, improve weight
my $tmpstr = $result{'__RAW__'}->{"$_"} || "";
if ( $tmpstr =~ /$biblionumber,\Q$title\E\-(\d+);/ ) {
my $weight = $1 + 1;
$result{'__RAW__'}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//;
$result{'__RAW__'}->{"$_"} .= "$biblionumber,$title-$weight;";
} else {
# get the value if it exist in the nozebra table, otherwise, create it
$sth2->execute( $server, '__RAW__', $_ );
my $existing_biblionumbers = $sth2->fetchrow;
# it exists
if ($existing_biblionumbers) {
$result{'__RAW__'}->{"$_"} = $existing_biblionumbers;
my $weight = ( $1 ? $1 : 0 ) + 1;
$result{'__RAW__'}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d+);//;
$result{'__RAW__'}->{"$_"} .= "$biblionumber,$title-$weight;";
# create a new ligne for this entry
} else {
$dbh->do( 'INSERT INTO nozebra SET server=' . $dbh->quote($server) . ', indexname="__RAW__",value=' . $dbh->quote($_) );
$result{'__RAW__'}->{"$_"} .= "$biblionumber,$title-1;";
}
}
}
}
}
}
return %result;
}
=head2 _koha_marc_update_bib_ids
@ -3641,17 +3305,10 @@ sub ModBiblioMarc {
$f005->update(sprintf("%4d%02d%02d%02d%02d%04.1f",@a)) if $f005;
}
my $oldRecord;
if ( C4::Context->preference("NoZebra") ) {
# only NoZebra indexing needs to have
# the previous version of the record
$oldRecord = GetMarcBiblio($biblionumber);
}
$sth = $dbh->prepare("UPDATE biblioitems SET marc=?,marcxml=? WHERE biblionumber=?");
$sth->execute( $record->as_usmarc(), $record->as_xml_record($encoding), $biblionumber );
$sth->finish;
ModZebra( $biblionumber, "specialUpdate", "biblioserver", $oldRecord, $record );
ModZebra( $biblionumber, "specialUpdate", "biblioserver" );
return $biblionumber;
}

View file

@ -38,7 +38,6 @@ C4::Installer
my ($fwk_language, $error_list) = $installer->load_sql_in_order($all_languages, @$list);
$installer->set_version_syspref();
$installer->set_marcflavour_syspref('MARC21');
$installer->set_indexing_engine(0);
=head1 DESCRIPTION
@ -430,31 +429,6 @@ sub set_marcflavour_syspref {
$request->execute;
}
=head2 set_indexing_engine
$installer->set_indexing_engine($nozebra);
Sets system preferences related to the indexing
engine. The C<$nozebra> argument is a boolean;
if true, turn on NoZebra mode and turn off QueryFuzzy,
QueryWeightFields, and QueryStemming. If false, turn
off NoZebra mode (i.e., use the Zebra search engine).
=cut
sub set_indexing_engine {
my $self = shift;
my $nozebra = shift;
if ($nozebra) {
$self->{'dbh'}->do("UPDATE systempreferences SET value=1 WHERE variable='NoZebra'");
$self->{'dbh'}->do("UPDATE systempreferences SET value=0 WHERE variable in ('QueryFuzzy','QueryWeightFields','QueryStemming')");
} else {
$self->{'dbh'}->do("UPDATE systempreferences SET value=0 WHERE variable='NoZebra'");
}
}
=head2 set_version_syspref
$installer->set_version_syspref();

View file

@ -295,7 +295,7 @@ sub AddItem {
my ( $itemnumber, $error ) = _koha_new_item( $item, $item->{barcode} );
$item->{'itemnumber'} = $itemnumber;
ModZebra( $item->{biblionumber}, "specialUpdate", "biblioserver", undef, undef );
ModZebra( $item->{biblionumber}, "specialUpdate", "biblioserver" );
logaction("CATALOGUING", "ADD", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
@ -549,7 +549,7 @@ sub ModItem {
# request that bib be reindexed so that searching on current
# item status is possible
ModZebra( $biblionumber, "specialUpdate", "biblioserver", undef, undef );
ModZebra( $biblionumber, "specialUpdate", "biblioserver" );
logaction("CATALOGUING", "MODIFY", $itemnumber, Dumper($item)) if C4::Context->preference("CataloguingLog");
}
@ -615,7 +615,7 @@ sub DelItem {
# get the MARC record
my $record = GetMarcBiblio($biblionumber);
ModZebra( $biblionumber, "specialUpdate", "biblioserver", undef, undef );
ModZebra( $biblionumber, "specialUpdate", "biblioserver" );
# backup the record
my $copy2deleted = $dbh->prepare("UPDATE deleteditems SET marc=? WHERE itemnumber=?");
@ -2173,8 +2173,8 @@ sub MoveItemFromBiblio {
$sth = $dbh->prepare("UPDATE items SET biblioitemnumber = ?, biblionumber = ? WHERE itemnumber = ? AND biblionumber = ?");
my $return = $sth->execute($tobiblioitem, $tobiblio, $itemnumber, $frombiblio);
if ($return == 1) {
ModZebra( $tobiblio, "specialUpdate", "biblioserver", undef, undef );
ModZebra( $frombiblio, "specialUpdate", "biblioserver", undef, undef );
ModZebra( $tobiblio, "specialUpdate", "biblioserver" );
ModZebra( $frombiblio, "specialUpdate", "biblioserver" );
# Checking if the item we want to move is in an order
require C4::Acquisition;
my $order = C4::Acquisition::GetOrderFromItemnumber($itemnumber);
@ -2460,18 +2460,12 @@ counts Usage of itemnumber in Analytical bibliorecords.
sub GetAnalyticsCount {
my ($itemnumber) = @_;
require C4::Search;
if (C4::Context->preference('NoZebra')) {
# Read the index Koha-Auth-Number for this authid and count the lines
my $result = C4::Search::NZanalyse("hi=$itemnumber");
my @tab = split /;/,$result;
return scalar @tab;
} else {
### ZOOM search here
my $query;
$query= "hi=".$itemnumber;
my ($err,$res,$result) = C4::Search::SimpleSearch($query,0,10);
return ($result);
}
### ZOOM search here
my $query;
$query= "hi=".$itemnumber;
my ($err,$res,$result) = C4::Search::SimpleSearch($query,0,10);
return ($result);
}
=head2 GetItemHolds

View file

@ -68,7 +68,6 @@ This module provides searching functions for Koha's bibliographic databases
&searchResults
&getRecords
&buildQuery
&NZgetRecords
&AddSearchHistory
&GetDistinctValues
&enabled_staff_search_views
@ -223,91 +222,82 @@ $template->param(result=>\@results);
sub SimpleSearch {
my ( $query, $offset, $max_results, $servers ) = @_;
if ( C4::Context->preference('NoZebra') ) {
my $result = NZorder( NZanalyse($query) )->{'biblioserver'};
my $search_result =
( $result->{hits}
&& $result->{hits} > 0 ? $result->{'RECORDS'} : [] );
return ( undef, $search_result, scalar($result->{hits}) );
return ( 'No query entered', undef, undef ) unless $query;
# FIXME hardcoded value. See catalog/search.pl & opac-search.pl too.
my @servers = defined ( $servers ) ? @$servers : ( 'biblioserver' );
my @zoom_queries;
my @tmpresults;
my @zconns;
my $results = [];
my $total_hits = 0;
my $QParser;
$QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser') && ! ($query =~ m/\w,\w|\w=\w/));
# Initialize & Search Zebra
for ( my $i = 0 ; $i < @servers ; $i++ ) {
eval {
$zconns[$i] = C4::Context->Zconn( $servers[$i], 1 );
if ($QParser) {
$query =~ s/=/:/g;
$QParser->parse( $query );
$query = $QParser->target_syntax($servers[$i]);
$zoom_queries[$i] = new ZOOM::Query::PQF( $query, $zconns[$i]);
} else {
$query =~ s/:/=/g;
$zoom_queries[$i] = new ZOOM::Query::CCL2RPN( $query, $zconns[$i]);
}
$tmpresults[$i] = $zconns[$i]->search( $zoom_queries[$i] );
# error handling
my $error =
$zconns[$i]->errmsg() . " ("
. $zconns[$i]->errcode() . ") "
. $zconns[$i]->addinfo() . " "
. $zconns[$i]->diagset();
return ( $error, undef, undef ) if $zconns[$i]->errcode();
};
if ($@) {
# caught a ZOOM::Exception
my $error =
$@->message() . " ("
. $@->code() . ") "
. $@->addinfo() . " "
. $@->diagset();
warn $error." for query: $query";
return ( $error, undef, undef );
}
}
else {
return ( 'No query entered', undef, undef ) unless $query;
# FIXME hardcoded value. See catalog/search.pl & opac-search.pl too.
my @servers = defined ( $servers ) ? @$servers : ( 'biblioserver' );
my @zoom_queries;
my @tmpresults;
my @zconns;
my $results = [];
my $total_hits = 0;
my $QParser;
$QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser') && ! ($query =~ m/\w,\w|\w=\w/));
_ZOOM_event_loop(
\@zconns,
\@tmpresults,
sub {
my ($i, $size) = @_;
my $first_record = defined($offset) ? $offset + 1 : 1;
my $hits = $tmpresults[ $i - 1 ]->size();
$total_hits += $hits;
my $last_record = $hits;
if ( defined $max_results && $offset + $max_results < $hits ) {
$last_record = $offset + $max_results;
}
# Initialize & Search Zebra
for ( my $i = 0 ; $i < @servers ; $i++ ) {
eval {
$zconns[$i] = C4::Context->Zconn( $servers[$i], 1 );
if ($QParser) {
$query =~ s/=/:/g;
$QParser->parse( $query );
$query = $QParser->target_syntax($servers[$i]);
$zoom_queries[$i] = new ZOOM::Query::PQF( $query, $zconns[$i]);
} else {
$query =~ s/:/=/g;
$zoom_queries[$i] = new ZOOM::Query::CCL2RPN( $query, $zconns[$i]);
}
$tmpresults[$i] = $zconns[$i]->search( $zoom_queries[$i] );
# error handling
my $error =
$zconns[$i]->errmsg() . " ("
. $zconns[$i]->errcode() . ") "
. $zconns[$i]->addinfo() . " "
. $zconns[$i]->diagset();
return ( $error, undef, undef ) if $zconns[$i]->errcode();
};
if ($@) {
# caught a ZOOM::Exception
my $error =
$@->message() . " ("
. $@->code() . ") "
. $@->addinfo() . " "
. $@->diagset();
warn $error." for query: $query";
return ( $error, undef, undef );
for my $j ( $first_record .. $last_record ) {
my $record =
$tmpresults[ $i - 1 ]->record( $j - 1 )->raw()
; # 0 indexed
push @{$results}, $record;
}
}
);
_ZOOM_event_loop(
\@zconns,
\@tmpresults,
sub {
my ($i, $size) = @_;
my $first_record = defined($offset) ? $offset + 1 : 1;
my $hits = $tmpresults[ $i - 1 ]->size();
$total_hits += $hits;
my $last_record = $hits;
if ( defined $max_results && $offset + $max_results < $hits ) {
$last_record = $offset + $max_results;
}
for my $j ( $first_record .. $last_record ) {
my $record =
$tmpresults[ $i - 1 ]->record( $j - 1 )->raw()
; # 0 indexed
push @{$results}, $record;
}
}
);
foreach my $zoom_query (@zoom_queries) {
$zoom_query->destroy();
}
return ( undef, $results, $total_hits );
foreach my $zoom_query (@zoom_queries) {
$zoom_query->destroy();
}
return ( undef, $results, $total_hits );
}
=head2 getRecords
@ -1267,14 +1257,6 @@ sub buildQuery {
my $fuzzy_enabled = C4::Context->preference("QueryFuzzy") || 0;
my $remove_stopwords = C4::Context->preference("QueryRemoveStopwords") || 0;
# no stemming/weight/fuzzy in NoZebra
if ( C4::Context->preference("NoZebra") ) {
$stemming = 0;
$weight_fields = 0;
$fuzzy_enabled = 0;
$auto_truncation = 0;
}
my $query = $operands[0];
my $simple_query = $operands[0];
@ -2171,602 +2153,6 @@ sub SearchAcquisitions{
$qdataacquisitions->finish;
return \@loopacquisitions;
}
#----------------------------------------------------------------------
#
# Non-Zebra GetRecords#
#----------------------------------------------------------------------
=head2 NZgetRecords
NZgetRecords has the same API as zera getRecords, even if some parameters are not managed
=cut
sub NZgetRecords {
my (
$query, $simple_query, $sort_by_ref, $servers_ref,
$results_per_page, $offset, $expanded_facet, $branches,
$query_type, $scan
) = @_;
warn "query =$query" if $DEBUG;
my $result = NZanalyse($query);
warn "results =$result" if $DEBUG;
return ( undef,
NZorder( $result, @$sort_by_ref[0], $results_per_page, $offset ),
undef );
}
=head2 NZanalyse
NZanalyse : get a CQL string as parameter, and returns a list of biblionumber;title,biblionumber;title,...
the list is built from an inverted index in the nozebra SQL table
note that title is here only for convenience : the sorting will be very fast when requested on title
if the sorting is requested on something else, we will have to reread all results, and that may be longer.
=cut
sub NZanalyse {
my ( $string, $server ) = @_;
# warn "---------" if $DEBUG;
warn " NZanalyse" if $DEBUG;
# warn "---------" if $DEBUG;
# $server contains biblioserver or authorities, depending on what we search on.
#warn "querying : $string on $server";
$server = 'biblioserver' unless $server;
# if we have a ", replace the content to discard temporarily any and/or/not inside
my $commacontent;
if ( $string =~ /"/ ) {
$string =~ s/"(.*?)"/__X__/;
$commacontent = $1;
warn "commacontent : $commacontent" if $DEBUG;
}
# split the query string in 3 parts : X AND Y means : $left="X", $operand="AND" and $right="Y"
# then, call again NZanalyse with $left and $right
# (recursive until we find a leaf (=> something without and/or/not)
# delete repeated operator... Would then go in infinite loop
while ( $string =~ s/( and| or| not| AND| OR| NOT)\1/$1/g ) {
}
#process parenthesis before.
if ( $string =~ /^\s*\((.*)\)(( and | or | not | AND | OR | NOT )(.*))?/ ) {
my $left = $1;
my $right = $4;
my $operator = lc($3); # FIXME: and/or/not are operators, not operands
warn
"dealing w/parenthesis before recursive sub call. left :$left operator:$operator right:$right"
if $DEBUG;
my $leftresult = NZanalyse( $left, $server );
if ($operator) {
my $rightresult = NZanalyse( $right, $server );
# OK, we have the results for right and left part of the query
# depending of operand, intersect, union or exclude both lists
# to get a result list
if ( $operator eq ' and ' ) {
return NZoperatorAND($leftresult,$rightresult);
}
elsif ( $operator eq ' or ' ) {
# just merge the 2 strings
return $leftresult . $rightresult;
}
elsif ( $operator eq ' not ' ) {
return NZoperatorNOT($leftresult,$rightresult);
}
}
else {
# this error is impossible, because of the regexp that isolate the operand, but just in case...
return $leftresult;
}
}
warn "string :" . $string if $DEBUG;
my $left = "";
my $right = "";
my $operator = "";
if ($string =~ /(.*?)( and | or | not | AND | OR | NOT )(.*)/) {
$left = $1;
$right = $3;
$operator = lc($2); # FIXME: and/or/not are operators, not operands
}
warn "no parenthesis. left : $left operator: $operator right: $right"
if $DEBUG;
# it's not a leaf, we have a and/or/not
if ($operator) {
# reintroduce comma content if needed
$right =~ s/__X__/"$commacontent"/ if $commacontent;
$left =~ s/__X__/"$commacontent"/ if $commacontent;
warn "node : $left / $operator / $right\n" if $DEBUG;
my $leftresult = NZanalyse( $left, $server );
my $rightresult = NZanalyse( $right, $server );
warn " leftresult : $leftresult" if $DEBUG;
warn " rightresult : $rightresult" if $DEBUG;
# OK, we have the results for right and left part of the query
# depending of operand, intersect, union or exclude both lists
# to get a result list
if ( $operator eq ' and ' ) {
return NZoperatorAND($leftresult,$rightresult);
}
elsif ( $operator eq ' or ' ) {
# just merge the 2 strings
return $leftresult . $rightresult;
}
elsif ( $operator eq ' not ' ) {
return NZoperatorNOT($leftresult,$rightresult);
}
else {
# this error is impossible, because of the regexp that isolate the operand, but just in case...
die "error : operand unknown : $operator for $string";
}
# it's a leaf, do the real SQL query and return the result
}
else {
$string =~ s/__X__/"$commacontent"/ if $commacontent;
$string =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|&|\+|\*|\// /g;
#remove trailing blank at the beginning
$string =~ s/^ //g;
warn "leaf:$string" if $DEBUG;
# parse the string in in operator/operand/value again
my $left = "";
my $operator = "";
my $right = "";
if ($string =~ /(.*)(>=|<=)(.*)/) {
$left = $1;
$operator = $2;
$right = $3;
} else {
$left = $string;
}
# warn "handling leaf... left:$left operator:$operator right:$right"
# if $DEBUG;
unless ($operator) {
if ($string =~ /(.*)(>|<|=)(.*)/) {
$left = $1;
$operator = $2;
$right = $3;
warn
"handling unless (operator)... left:$left operator:$operator right:$right"
if $DEBUG;
} else {
$left = $string;
}
}
my $results;
# strip adv, zebra keywords, currently not handled in nozebra: wrdl, ext, phr...
$left =~ s/ .*$//;
# automatic replace for short operators
$left = 'title' if $left =~ '^ti$';
$left = 'author' if $left =~ '^au$';
$left = 'publisher' if $left =~ '^pb$';
$left = 'subject' if $left =~ '^su$';
$left = 'koha-Auth-Number' if $left =~ '^an$';
$left = 'keyword' if $left =~ '^kw$';
$left = 'itemtype' if $left =~ '^mc$'; # Fix for Bug 2599 - Search limits not working for NoZebra
warn "handling leaf... left:$left operator:$operator right:$right" if $DEBUG;
my $dbh = C4::Context->dbh;
if ( $operator && $left ne 'keyword' ) {
#do a specific search
$operator = 'LIKE' if $operator eq '=' and $right =~ /%/;
my $sth = $dbh->prepare(
"SELECT biblionumbers,value FROM nozebra WHERE server=? AND indexname=? AND value $operator ?"
);
warn "$left / $operator / $right\n" if $DEBUG;
# split each word, query the DB and build the biblionumbers result
#sanitizing leftpart
$left =~ s/^\s+|\s+$//;
foreach ( split / /, $right ) {
my $biblionumbers;
$_ =~ s/^\s+|\s+$//;
next unless $_;
warn "EXECUTE : $server, $left, $_" if $DEBUG;
$sth->execute( $server, $left, $_ )
or warn "execute failed: $!";
while ( my ( $line, $value ) = $sth->fetchrow ) {
# if we are dealing with a numeric value, use only numeric results (in case of >=, <=, > or <)
# otherwise, fill the result
$biblionumbers .= $line
unless ( $right =~ /^\d+$/ && $value =~ /\D/ );
warn "result : $value "
. ( $right =~ /\d/ ) . "=="
. ( $value =~ /\D/?$line:"" ) if $DEBUG; #= $line";
}
# do a AND with existing list if there is one, otherwise, use the biblionumbers list as 1st result list
if ($results) {
warn "NZAND" if $DEBUG;
$results = NZoperatorAND($biblionumbers,$results);
} else {
$results = $biblionumbers;
}
}
}
else {
#do a complete search (all indexes), if index='kw' do complete search too.
my $sth = $dbh->prepare(
"SELECT biblionumbers FROM nozebra WHERE server=? AND value LIKE ?"
);
# split each word, query the DB and build the biblionumbers result
foreach ( split / /, $string ) {
next if C4::Context->stopwords->{ uc($_) }; # skip if stopword
warn "search on all indexes on $_" if $DEBUG;
my $biblionumbers;
next unless $_;
$sth->execute( $server, $_ );
while ( my $line = $sth->fetchrow ) {
$biblionumbers .= $line;
}
# do a AND with existing list if there is one, otherwise, use the biblionumbers list as 1st result list
if ($results) {
$results = NZoperatorAND($biblionumbers,$results);
}
else {
warn "NEW RES for $_ = $biblionumbers" if $DEBUG;
$results = $biblionumbers;
}
}
}
warn "return : $results for LEAF : $string" if $DEBUG;
return $results;
}
warn "---------\nLeave NZanalyse\n---------" if $DEBUG;
}
sub NZoperatorAND{
my ($rightresult, $leftresult)=@_;
my @leftresult = split /;/, $leftresult;
warn " @leftresult / $rightresult \n" if $DEBUG;
# my @rightresult = split /;/,$leftresult;
my $finalresult;
# parse the left results, and if the biblionumber exist in the right result, save it in finalresult
# the result is stored twice, to have the same weight for AND than OR.
# example : TWO : 61,61,64,121 (two is twice in the biblio #61) / TOWER : 61,64,130
# result : 61,61,61,61,64,64 for two AND tower : 61 has more weight than 64
foreach (@leftresult) {
my $value = $_;
my $countvalue;
( $value, $countvalue ) = ( $1, $2 ) if ($value=~/(.*)-(\d+)$/);
if ( $rightresult =~ /\Q$value\E-(\d+);/ ) {
$countvalue = ( $1 > $countvalue ? $countvalue : $1 );
$finalresult .=
"$value-$countvalue;$value-$countvalue;";
}
}
warn "NZAND DONE : $finalresult \n" if $DEBUG;
return $finalresult;
}
sub NZoperatorOR{
my ($rightresult, $leftresult)=@_;
return $rightresult.$leftresult;
}
sub NZoperatorNOT{
my ($leftresult, $rightresult)=@_;
my @leftresult = split /;/, $leftresult;
# my @rightresult = split /;/,$leftresult;
my $finalresult;
foreach (@leftresult) {
my $value=$_;
$value=$1 if $value=~m/(.*)-\d+$/;
unless ($rightresult =~ "$value-") {
$finalresult .= "$_;";
}
}
return $finalresult;
}
=head2 NZorder
$finalresult = NZorder($biblionumbers, $ordering,$results_per_page,$offset);
TODO :: Description
=cut
sub NZorder {
my ( $biblionumbers, $ordering, $results_per_page, $offset ) = @_;
warn "biblionumbers = $biblionumbers and ordering = $ordering\n" if $DEBUG;
# order title asc by default
# $ordering = '1=36 <i' unless $ordering;
$results_per_page = 20 unless $results_per_page;
$offset = 0 unless $offset;
my $dbh = C4::Context->dbh;
#
# order by POPULARITY
#
if ( $ordering =~ /popularity/ ) {
my %result;
my %popularity;
# popularity is not in MARC record, it's builded from a specific query
my $sth =
$dbh->prepare("select sum(issues) from items where biblionumber=?");
foreach ( split /;/, $biblionumbers ) {
my ( $biblionumber, $title ) = split /,/, $_;
$result{$biblionumber} = GetMarcBiblio($biblionumber);
$sth->execute($biblionumber);
my $popularity = $sth->fetchrow || 0;
# hint : the key is popularity.title because we can have
# many results with the same popularity. In this case, sub-ordering is done by title
# we also have biblionumber to avoid bug for 2 biblios with the same title & popularity
# (un-frequent, I agree, but we won't forget anything that way ;-)
$popularity{ sprintf( "%10d", $popularity ) . $title
. $biblionumber } = $biblionumber;
}
# sort the hash and return the same structure as GetRecords (Zebra querying)
my $result_hash;
my $numbers = 0;
if ( $ordering eq 'popularity_dsc' ) { # sort popularity DESC
foreach my $key ( sort { $b cmp $a } ( keys %popularity ) ) {
$result_hash->{'RECORDS'}[ $numbers++ ] =
$result{ $popularity{$key} }->as_usmarc();
}
}
else { # sort popularity ASC
foreach my $key ( sort ( keys %popularity ) ) {
$result_hash->{'RECORDS'}[ $numbers++ ] =
$result{ $popularity{$key} }->as_usmarc();
}
}
my $finalresult = ();
$result_hash->{'hits'} = $numbers;
$finalresult->{'biblioserver'} = $result_hash;
return $finalresult;
#
# ORDER BY author
#
}
elsif ( $ordering =~ /author/ ) {
my %result;
foreach ( split /;/, $biblionumbers ) {
my ( $biblionumber, $title ) = split /,/, $_;
my $record = GetMarcBiblio($biblionumber);
my $author;
if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
$author = $record->subfield( '200', 'f' );
$author = $record->subfield( '700', 'a' ) unless $author;
}
else {
$author = $record->subfield( '100', 'a' );
}
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
# and we don't want to get only 1 result for each of them !!!
$result{ $author . $biblionumber } = $record;
}
# sort the hash and return the same structure as GetRecords (Zebra querying)
my $result_hash;
my $numbers = 0;
if ( $ordering eq 'author_za' || $ordering eq 'author_dsc' ) { # sort by author desc
foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
$result_hash->{'RECORDS'}[ $numbers++ ] =
$result{$key}->as_usmarc();
}
}
else { # sort by author ASC
foreach my $key ( sort ( keys %result ) ) {
$result_hash->{'RECORDS'}[ $numbers++ ] =
$result{$key}->as_usmarc();
}
}
my $finalresult = ();
$result_hash->{'hits'} = $numbers;
$finalresult->{'biblioserver'} = $result_hash;
return $finalresult;
#
# ORDER BY callnumber
#
}
elsif ( $ordering =~ /callnumber/ ) {
my %result;
foreach ( split /;/, $biblionumbers ) {
my ( $biblionumber, $title ) = split /,/, $_;
my $record = GetMarcBiblio($biblionumber);
my $callnumber;
my $frameworkcode = GetFrameworkCode($biblionumber);
my ( $callnumber_tag, $callnumber_subfield ) = GetMarcFromKohaField( 'items.itemcallnumber', $frameworkcode);
( $callnumber_tag, $callnumber_subfield ) = GetMarcFromKohaField('biblioitems.callnumber', $frameworkcode)
unless $callnumber_tag;
if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
$callnumber = $record->subfield( '200', 'f' );
} else {
$callnumber = $record->subfield( '100', 'a' );
}
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
# and we don't want to get only 1 result for each of them !!!
$result{ $callnumber . $biblionumber } = $record;
}
# sort the hash and return the same structure as GetRecords (Zebra querying)
my $result_hash;
my $numbers = 0;
if ( $ordering eq 'call_number_dsc' ) { # sort by title desc
foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
$result_hash->{'RECORDS'}[ $numbers++ ] =
$result{$key}->as_usmarc();
}
}
else { # sort by title ASC
foreach my $key ( sort { $a cmp $b } ( keys %result ) ) {
$result_hash->{'RECORDS'}[ $numbers++ ] =
$result{$key}->as_usmarc();
}
}
my $finalresult = ();
$result_hash->{'hits'} = $numbers;
$finalresult->{'biblioserver'} = $result_hash;
return $finalresult;
}
elsif ( $ordering =~ /pubdate/ ) { #pub year
my %result;
foreach ( split /;/, $biblionumbers ) {
my ( $biblionumber, $title ) = split /,/, $_;
my $record = GetMarcBiblio($biblionumber);
my ( $publicationyear_tag, $publicationyear_subfield ) =
GetMarcFromKohaField( 'biblioitems.publicationyear', '' );
my $publicationyear =
$record->subfield( $publicationyear_tag,
$publicationyear_subfield );
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
# and we don't want to get only 1 result for each of them !!!
$result{ $publicationyear . $biblionumber } = $record;
}
# sort the hash and return the same structure as GetRecords (Zebra querying)
my $result_hash;
my $numbers = 0;
if ( $ordering eq 'pubdate_dsc' ) { # sort by pubyear desc
foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
$result_hash->{'RECORDS'}[ $numbers++ ] =
$result{$key}->as_usmarc();
}
}
else { # sort by pub year ASC
foreach my $key ( sort ( keys %result ) ) {
$result_hash->{'RECORDS'}[ $numbers++ ] =
$result{$key}->as_usmarc();
}
}
my $finalresult = ();
$result_hash->{'hits'} = $numbers;
$finalresult->{'biblioserver'} = $result_hash;
return $finalresult;
#
# ORDER BY title
#
}
elsif ( $ordering =~ /title/ ) {
# the title is in the biblionumbers string, so we just need to build a hash, sort it and return
my %result;
foreach ( split /;/, $biblionumbers ) {
my ( $biblionumber, $title ) = split /,/, $_;
# hint : the result is sorted by title.biblionumber because we can have X biblios with the same title
# and we don't want to get only 1 result for each of them !!!
# hint & speed improvement : we can order without reading the record
# so order, and read records only for the requested page !
$result{ $title . $biblionumber } = $biblionumber;
}
# sort the hash and return the same structure as GetRecords (Zebra querying)
my $result_hash;
my $numbers = 0;
if ( $ordering eq 'title_az' ) { # sort by title desc
foreach my $key ( sort ( keys %result ) ) {
$result_hash->{'RECORDS'}[ $numbers++ ] = $result{$key};
}
}
else { # sort by title ASC
foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
$result_hash->{'RECORDS'}[ $numbers++ ] = $result{$key};
}
}
# limit the $results_per_page to result size if it's more
$results_per_page = $numbers - 1 if $numbers < $results_per_page;
# for the requested page, replace biblionumber by the complete record
# speed improvement : avoid reading too much things
for (
my $counter = $offset ;
$counter <= $offset + $results_per_page ;
$counter++
)
{
$result_hash->{'RECORDS'}[$counter] =
GetMarcBiblio( $result_hash->{'RECORDS'}[$counter] )->as_usmarc;
}
my $finalresult = ();
$result_hash->{'hits'} = $numbers;
$finalresult->{'biblioserver'} = $result_hash;
return $finalresult;
}
else {
#
# order by ranking
#
# we need 2 hashes to order by ranking : the 1st one to count the ranking, the 2nd to order by ranking
my %result;
my %count_ranking;
foreach ( split /;/, $biblionumbers ) {
my ( $biblionumber, $title ) = split /,/, $_;
$title =~ /(.*)-(\d)/;
# get weight
my $ranking = $2;
# note that we + the ranking because ranking is calculated on weight of EACH term requested.
# if we ask for "two towers", and "two" has weight 2 in biblio N, and "towers" has weight 4 in biblio N
# biblio N has ranking = 6
$count_ranking{$biblionumber} += $ranking;
}
# build the result by "inverting" the count_ranking hash
# 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
# warn "counting";
foreach ( keys %count_ranking ) {
$result{ sprintf( "%10d", $count_ranking{$_} ) . '-' . $_ } = $_;
}
# sort the hash and return the same structure as GetRecords (Zebra querying)
my $result_hash;
my $numbers = 0;
foreach my $key ( sort { $b cmp $a } ( keys %result ) ) {
$result_hash->{'RECORDS'}[ $numbers++ ] = $result{$key};
}
# limit the $results_per_page to result size if it's more
$results_per_page = $numbers - 1 if $numbers < $results_per_page;
# for the requested page, replace biblionumber by the complete record
# speed improvement : avoid reading too much things
for (
my $counter = $offset ;
$counter <= $offset + $results_per_page ;
$counter++
)
{
$result_hash->{'RECORDS'}[$counter] =
GetMarcBiblio( $result_hash->{'RECORDS'}[$counter] )->as_usmarc
if $result_hash->{'RECORDS'}[$counter];
}
my $finalresult = ();
$result_hash->{'hits'} = $numbers;
$finalresult->{'biblioserver'} = $result_hash;
return $finalresult;
}
}
=head2 enabled_staff_search_views

View file

@ -1169,7 +1169,6 @@ MySQL> show tables;
| matchpoint_components |
| matchpoints |
| notifys |
| nozebra |
| opac_news |
| overduerules |
| printers |
@ -1258,7 +1257,7 @@ Connect to Koha: HYPERLINK "http://localhost:8080/" http://localhost:8080 and us
-- A Phase 3, click on Install the basic settings (screen 1), select the declination Marc (Unimarc_complet in our
Where Unimarc_lecture_pub; screen 2), select default settings and then click on Import (only settings obligat
oires are checked by default; screen 3);
-- The screen 4 summarizes what has been imported, while low demand to opt for a configuration Zebra (our choice) or NoZebra;
-- The screen 4 summarizes what has been imported;
-- Finally, the screen 5 indicates the end of the installation; then you just have to click Finish.
Complements

View file

@ -61,7 +61,6 @@ $apacheVersion = (`/usr/sbin/apache2 -V`)[0] unless $apacheVersion;
my $zebraVersion = `zebraidx -V`;
# Additional system information for warnings
my $prefNoZebra = C4::Context->preference('nozebra');
my $prefAutoCreateAuthorities = C4::Context->preference('AutoCreateAuthorities');
my $prefBiblioAddsAuthorities = C4::Context->preference('BiblioAddsAuthorities');
my $warnPrefBiblioAddsAuthorities = ( $prefAutoCreateAuthorities && ( !$prefBiblioAddsAuthorities) );
@ -83,7 +82,6 @@ $template->param(
mysqlVersion => $mysqlVersion,
apacheVersion => $apacheVersion,
zebraVersion => $zebraVersion,
prefNoZebra => $prefNoZebra,
prefBiblioAddsAuthorities => $prefBiblioAddsAuthorities,
prefAutoCreateAuthorities => $prefAutoCreateAuthorities,
warnPrefBiblioAddsAuthorities => $warnPrefBiblioAddsAuthorities,

View file

@ -517,18 +517,10 @@ my $facets; # this object stores the faceted results that display on the left-ha
my @results_array;
my $results_hashref;
if (C4::Context->preference('NoZebra')) {
$query=~s/yr(:|=)\s*([\d]{1,4})-([\d]{1,4})/(yr>=$2 and yr<=$3)/g;
$simple_query=~s/yr\s*(:|=)([\d]{1,4})-([\d]{1,4})/(yr>=$2 and yr<=$3)/g;
# warn $query;
eval {
($error, $results_hashref, $facets) = NZgetRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$query_type,$scan);
};
} else {
eval {
($error, $results_hashref, $facets) = getRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$itemtypes,$query_type,$scan);
};
}
eval {
($error, $results_hashref, $facets) = getRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$itemtypes,$query_type,$scan);
};
# This sorts the facets into alphabetical order
if ($facets) {
foreach my $f (@$facets) {

View file

@ -1377,20 +1377,6 @@ CREATE TABLE `notifys` (
`method` varchar(20) NOT NULL default ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table structure for table `nozebra`
--
DROP TABLE IF EXISTS `nozebra`;
CREATE TABLE `nozebra` (
`server` varchar(20) NOT NULL,
`indexname` varchar(40) NOT NULL,
`value` varchar(250) NOT NULL,
`biblionumbers` longtext NOT NULL,
KEY `indexname` (`server`,`indexname`),
KEY `value` (`server`,`value`))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table structure for table `oai_sets`
--

View file

@ -32,5 +32,3 @@ UPDATE systempreferences SET value = '1' WHERE variable = 'patronimages';
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';
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';

View file

@ -47,8 +47,6 @@ UPDATE systempreferences SET value='942hv' WHERE variable='itemcallnumber';
UPDATE systempreferences SET value='UNIMARC' WHERE variable='marcflavour';
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';
-- Circulation - Оборот
-- I18N/L10N

View file

@ -115,7 +115,6 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('z3950NormalizeAuthor',0,'If ON, Personal Name Authorities will replace authors in biblio.author','','YesNo');
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');
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');
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');
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');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('CircAutocompl',1,'If ON, autocompletion is enabled for the Circulation input',NULL,'YesNo');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('RoutingSerials',1,'If ON, serials routing is enabled',NULL,'YesNo');
@ -174,8 +173,6 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
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');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('language','en','Set the default language in the staff client.',NULL,'Languages');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('QueryAutoTruncate',1,'If ON, query truncation is enabled by default',NULL,'YesNo');
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');
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');
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');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('PatronsPerPage','20','Number of Patrons Per Page displayed by default','20','Integer');
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');

View file

@ -31,31 +31,3 @@ UPDATE systempreferences SET value = 'Тут будуть важливі пос
UPDATE systempreferences SET value = '1' WHERE variable = 'patronimages';
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';
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',
'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',
'se' => '225a',
'isbn' => '010a',
'issn' => '011a',
'biblionumber' => '9999',
'itemtype' => '200b,942c,952y',
'language' => '101a',
'pl' => '210a',
'publisher' => '210c',
'date' => '210d',
'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',
'Koha-Auth-Number' => '6009,6019,6029,6039,6049,6059,6069,6109,7009,7019,7029,7109,7119,7129',
'subject' => '600*,601*,606*,610*',
'an' => '6009,6019,6069,6109,6079',
'su' => '600a,601a,606a,610a,607a,608a',
'lcn' => '686a,952o',
'yr' => '210d',
'mt' => '200b',
'dewey' => '676a',
'bc' => '952p',
'callnum' => '952o',
'homebranch' => '952a,952c',
'host-item' => '992b,992c',
'keyword' => '200*,600*,700*,400*,210*'
" WHERE variable = 'NoZebraIndexes';

View file

@ -47,34 +47,6 @@ UPDATE systempreferences SET value='942hv' WHERE variable='itemcallnumber';
UPDATE systempreferences SET value='UNIMARC' WHERE variable='marcflavour';
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',
'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',
'se' => '225a',
'isbn' => '010a',
'issn' => '011a',
'biblionumber' => '9999',
'itemtype' => '200b,942c,952y',
'language' => '101a',
'pl' => '210a',
'publisher' => '210c',
'date' => '210d',
'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',
'Koha-Auth-Number' => '6009,6019,6029,6039,6049,6059,6069,6109,7009,7019,7029,7109,7119,7129',
'subject' => '600*,601*,606*,610*',
'an' => '6009,6019,6069,6109,6079',
'su' => '600a,601a,606a,610a,607a,608a',
'lcn' => '686a,952o',
'yr' => '210d',
'mt' => '200b',
'dewey' => '676a',
'bc' => '952p',
'callnum' => '952o',
'homebranch' => '952a,952c',
'host-item' => '992b,992c',
'keyword' => '200*,600*,700*,400*,210*'
" WHERE variable='NoZebraIndexes';
-- Circulation - Обіг
-- I18N/L10N

View file

@ -6538,6 +6538,18 @@ if ( CheckVersion($DBversion) ) {
SetVersion ($DBversion);
}
$DBversion = "3.11.00.102";
if ( CheckVersion($DBversion) ) {
$dbh->do(q{
DELETE FROM systempreferences WHERE variable='NoZebra'
});
$dbh->do(q{
DELETE FROM systempreferences WHERE variable='QueryRemoveStopwords'
});
print "Upgrade to $DBversion done (Remove deprecated NoZebra and QueryRemoveStopwords sysprefs)\n";
SetVersion($DBversion);
}
=head1 FUNCTIONS
=head2 TableExists($table)

View file

@ -189,7 +189,6 @@ elsif ( $step && $step == 3 ) {
}
elsif ( $op && $op eq 'finish' ) {
$installer->set_version_syspref();
$installer->set_indexing_engine(0); # use Zebra
# Installation is finished.
# We just deny anybody access to install

View file

@ -60,7 +60,6 @@
<h5>Additional parameters</h5>
<ul>
[% IF ( NoZebra ) %]<li><a href="/cgi-bin/koha/admin/stopwords.pl">Stop words</a></li>[% END %]
<!-- <li><a href="/cgi-bin/koha/admin/printers.pl">Network Printers</a></li> -->
<li><a href="/cgi-bin/koha/admin/z3950servers.pl">Z39.50 client targets</a></li>
<li><a href="/cgi-bin/koha/admin/didyoumean.pl">Did you mean?</a></li>

View file

@ -104,12 +104,9 @@
<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>
[% END %]
<h2>Warnings regarding the system configuration</h2>
[% IF ( (prefNoZebra) || (warnPrefBiblioAddsAuthorities) || warnPrefEasyAnalyticalRecords ) %]
[% IF ( (warnPrefBiblioAddsAuthorities) || warnPrefEasyAnalyticalRecords ) %]
<table>
<caption>Preferences</caption>
[% IF (prefNoZebra) %]
<tr><th scope="row"><b>Warning</b> </th><td>System preference 'nozebra' set. Deprectated!</td></tr>
[% END %]
[% IF (warnPrefBiblioAddsAuthorities) %]
<tr><th scope="row"><b>Warning</b> </th><td>System preference 'AutoCreateAuthorities' set, but needs 'BiblioAddsAuthorities' set as well.</td></tr>
[% END %]

View file

@ -101,8 +101,6 @@
<h3>Additional parameters</h3>
<dl>
[% IF ( NoZebra ) %]<dt><a href="/cgi-bin/koha/admin/stopwords.pl">Stop words</a></dt>
<dd>Words ignored during search.</dd>[% END %]
<!-- <dt><a href="/cgi-bin/koha/admin/printers.pl">Network Printers</a></dt>
<dd>Printers (UNIX paths).</dd> -->
<dt><a href="/cgi-bin/koha/admin/z3950servers.pl">Z39.50 client targets</a></dt>

View file

@ -390,46 +390,6 @@ var holdForPatron = function () {
</form>
[% ELSE %]
[% IF ( NoZebra ) %]
<!-- ######### -->
<div id="facets">
<dl>
<!-- FACETS START -->
[% IF ( opacfacets ) %]
<dt id="facets1" onclick="var Elt=document.getElementById('facets_list');if (Elt.style.display!='block'){Elt.style.display='block';} else {Elt.style.display='none';}">
Refine your search
</dt>
<dd id="facets_list" style="display:none;">
<ul>
[% FOREACH facets_loo IN facets_loop %]
<li id="[% facets_loo.type_id %]">[% facets_loo.type_label %]
<ul>
[% FOREACH facet IN facets_loo.facets %]
<li>
<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 %]">
[% facet.facet_label_value %]
</a> ([% facet.facet_count %])
</li>
[% END %]
[% IF ( facets_loo.expandable ) %]
<li class="showmore">
<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 %]">
Show more
</a>
</li>
[% END %]
</ul>
</li>
[% END %]
</ul>
</dd>
[% END %]
<!-- FACETS END -->
</dl>
</div>
<!-- ######### -->
<!-- NoZebra -->[% END %]
<div id="searchresults">
<form action="/cgi-bin/koha/catalogue/search.pl" method="get" name="bookbag_form" id="bookbag_form">
[% IF ( searchdesc ) %]

View file

@ -2,8 +2,6 @@
<h1>Stop Words</h1>
<p style="color: #990000">Important: If NoZebra is set to 'Use' this option will not appear on the administration menu</p>
<p>Stop words are words that you want the search system to ignore.</p>
<p>Koha comes with a standard list of stop words that can be edited by visiting the Stop Word administration area.</p>

View file

@ -16,7 +16,7 @@ the kohaversion is divided in 4 parts :
use strict;
sub kohaversion {
our $VERSION = '3.11.00.101';
our $VERSION = '3.11.00.102';
# version needs to be set this way
# so that it can be picked up by Makefile.PL
# during install

View file

@ -1,343 +0,0 @@
#!/usr/bin/perl
use C4::Context;
use Getopt::Long;
use C4::Biblio;
use C4::AuthoritiesMarc;
use strict;
#use warnings; FIXME - Bug 2505
#
# script that fills the nozebra table
#
#
$|=1; # flushes output
# limit for database dumping
my $limit;# = "LIMIT 100";
my $directory;
#my $skip_export;
#my $keep_export;
#my $reset;
#my $biblios;
my $authorities;
my $sysprefs;
my $commit;
my $want_help;
my $result = GetOptions(
'd:s' => \$directory,
# 'reset' => \$reset,
# 's' => \$skip_export, # Not used and conflicts with 's' option some lines below for sysprefs!!!
# 'k' => \$keep_export,
# 'b' => \$biblios,
# 'a' => \$authorities,
's' => \$sysprefs, # rebuild 'NoZebraIndexes' syspref
'h|help' => \$want_help,
'commit:f' => \$commit,
);
if (not $result or $want_help) {
print_usage();
exit 0;
}
sub print_usage {
print <<_USAGE_;
$0: reindex MARC bibs and authorities if NOT using Zebra ("NoZebra").
Use this batch job to reindex all biblio and authority
records in your Koha database. This job is useful
only if you are NOT using Zebra ('NoZebra'); if you are
using the 'Zebra'mode, this job should NOT be used.
Parameters:
-d Temporary directory for indexing.
If not specified, one is automatically
created. The export directory
is automatically deleted unless
you supply the -k switch.
-s Rebuild "NoZebraIndexes" System Preference
--help or -h show this message.
_USAGE_
} # END of print_usage sub
my $commitnum = 1000;
$commitnum = $commit if ($commit) ;
$directory = "export" unless $directory;
my $dbh=C4::Context->dbh;
$dbh->do("update systempreferences set value=1 where variable='NoZebra'");
$dbh->do("truncate nozebra");
my %index = GetNoZebraIndexes();
if (!%index || $sysprefs ) {
if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
$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',
'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',
'isbn' => '010a',
'issn' => '011a',
'biblionumber' =>'0909',
'itemtype' => '200b',
'language' => '101a',
'publisher' => '210c',
'date' => '210d',
'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',
'Koha-Auth-Number' => '6009,6019,6029,6039,6049,6059,6069,6109,7009,7019,7029,7109,7119,7129',
'subject' => '600*,601*,606*,610*',
'dewey' => '676a',
'host-item' => '995a,995c',\" where variable='NoZebraIndexes'");
%index = GetNoZebraIndexes();
} elsif (C4::Context->preference('marcflavour') eq 'MARC21') {
$dbh->do("UPDATE systempreferences SET value=\"
'title' => '130a,210a,222a,240a,243a,245a,245b,246a,246b,247a,247b,250a,250b,440a,830a',
'author' => '100a,100b,100c,100d,110a,111a,111b,111c,111d,245c,700a,710a,711a,800a,810a,811a',
'isbn' => '020a',
'issn' => '022a',
'lccn' => '010a',
'biblionumber => '999c',
'itemtype' => '942c',
'publisher' => '260b',
'date' => '260c',
'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',
'subject' => '600*,610*,611*,630*,650*,651*,653*,654*,655*,662*,690*',
'dewey' => '082',
'bc' => '952p',
'callnum' => '952o',
'an' => '6009,6109,6119',
'series' => 440*,490*,
'host-item' => '9529
'shelf' => '952c',
'collection' => '9528',
\"WHERE variable='NoZebraIndexes'");
%index = GetNoZebraIndexes();
}
}
$|=1;
$dbh->{AutoCommit} = 0;
print "***********************************\n";
print "***** building BIBLIO indexes *****\n";
print "***********************************\n";
my $sth;
$sth=$dbh->prepare("select biblionumber from biblioitems order by biblionumber $limit");
$sth->execute();
my $i=0;
my %result;
while (my ($biblionumber) = $sth->fetchrow) {
$i++;
print "\r$i";
my $record;
eval{
$record = GetMarcBiblio($biblionumber);
};
if($@){
print " There was some pb getting biblionumber : ".$biblionumber."\n";
next;
}
next unless $record;
# get title of the record (to store the 10 first letters with the index)
my ($titletag,$titlesubfield) = GetMarcFromKohaField('biblio.title', '');
my $title = lc($record->subfield($titletag,$titlesubfield));
# remove blancks comma (that could cause problem when decoding the string for CQL retrieval) and regexp specific values
$title =~ s/ |\.|,|;|\[|\]|\(|\)|\*|-|'|=|://g;
# limit to 10 char, should be enough, and limit the DB size
$title = substr($title,0,10);
#parse each field
foreach my $field ($record->fields()) {
#parse each subfield
next if $field->tag <10;
foreach my $subfield ($field->subfields()) {
my $tag = $field->tag();
my $subfieldcode = $subfield->[0];
my $indexed=0;
# check each index to see if the subfield is stored somewhere
# otherwise, store it in __RAW__ index
foreach my $key (keys %index) {
if ($index{$key} =~ /\Q$tag\E\*/ or $index{$key} =~ /\Q$tag$subfieldcode\E/) {
$indexed=1;
my $line= lc $subfield->[1];
# remove meaningless value in the field...
$line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:/ /g;
# ... and split in words
foreach (split / /,$line) {
next unless $_; # skip empty values (multiple spaces)
# remove any accented char
# if the entry is already here, improve weight
if ($result{$key}->{"$_"} =~ /$biblionumber,\Q$title\E\-(\d);/) {
my $weight=$1+1;
$result{$key}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d);//;
$result{$key}->{"$_"} .= "$biblionumber,$title-$weight;";
# otherwise, create it, with weight=1
} else {
$result{$key}->{"$_"}.="$biblionumber,$title-1;";
}
}
}
}
# the subfield is not indexed, store it in __RAW__ index anyway
unless ($indexed) {
my $line= lc $subfield->[1];
$line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=/ /g;
foreach (split / /,$line) {
next unless $_;
# warn $record->as_formatted."$_ =>".$title;
if ($result{__RAW__}->{"$_"} =~ /$biblionumber,\Q$title\E\-(\d);/) {
my $weight=$1+1;
# $weight++;
$result{__RAW__}->{"$_"} =~ s/$biblionumber,\Q$title\E\-(\d);//;
$result{__RAW__}->{"$_"} .= "$biblionumber,$title-$weight;";
} else {
$result{__RAW__}->{"$_"}.="$biblionumber,$title-1;";
}
}
}
}
}
}
print "\nInserting records...\n";
$i=0;
my $commitnum = 100;
$dbh->{AutoCommit} = 0;
$sth = $dbh->prepare("INSERT INTO nozebra (server,indexname,value,biblionumbers) VALUES ('biblioserver',?,?,?)");
foreach my $key (keys %result) {
foreach my $index (keys %{$result{$key}}) {
if (length($result{$key}->{$index}) > 1000000) {
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";
}
print "\r$i";
$i++;
$sth->execute($key,$index,$result{$key}->{$index});
$dbh->commit() if (0 == $i % $commitnum);
}
$dbh->commit() if (0 == $i % $commitnum);
}
$dbh->commit;
print "\nbiblios done\n";
print "\n***********************************\n";
print "***** building AUTHORITIES indexes *****\n";
print "***********************************\n";
$sth=$dbh->prepare("select authid from auth_header order by authid $limit");
$sth->execute();
$i=0;
%result = ();
while (my ($authid) = $sth->fetchrow) {
$i++;
print "\r$i";
my $record;
eval{
$record = GetAuthority($authid);
};
if($@){
print " There was some pb getting authnumber : ".$authid."\n";
next;
}
my %index;
# for authorities, the "title" is the $a mainentry
my $authref = C4::AuthoritiesMarc::GetAuthType(C4::AuthoritiesMarc::GetAuthTypeCode($authid));
warn "ERROR : authtype undefined for ".$record->as_formatted unless $authref;
my $title = $record->subfield($authref->{auth_tag_to_report},'a');
$index{'mainmainentry'}= $authref->{'auth_tag_to_report'}.'a';
$index{'mainentry'} = $authref->{'auth_tag_to_report'}.'*';
$index{'auth_type'} = '152b';
# remove blancks comma (that could cause problem when decoding the string for CQL retrieval) and regexp specific values
$title =~ s/ |\.|,|;|\[|\]|\(|\)|\*|-|'|:|=//g;
$title = quotemeta $title;
# limit to 10 char, should be enough, and limit the DB size
$title = substr($title,0,10);
#parse each field
foreach my $field ($record->fields()) {
#parse each subfield
next if $field->tag <10;
foreach my $subfield ($field->subfields()) {
my $tag = $field->tag();
my $subfieldcode = $subfield->[0];
my $indexed=0;
# check each index to see if the subfield is stored somewhere
# otherwise, store it in __RAW__ index
foreach my $key (keys %index) {
if ($index{$key} =~ /$tag\*/ or $index{$key} =~ /$tag$subfieldcode/) {
$indexed=1;
my $line= lc $subfield->[1];
# remove meaningless value in the field...
$line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:/ /g;
# ... and split in words
foreach (split / /,$line) {
next unless $_; # skip empty values (multiple spaces)
# if the entry is already here, improve weight
if ($result{$key}->{"$_"} =~ /$authid,$title\-(\d);/) {
my $weight=$1+1;
$result{$key}->{"$_"} =~ s/$authid,$title\-(\d);//;
$result{$key}->{"$_"} .= "$authid,$title-$weight;";
# otherwise, create it, with weight=1
} else {
$result{$key}->{"$_"}.="$authid,$title-1;";
}
}
}
}
# the subfield is not indexed, store it in __RAW__ index anyway
unless ($indexed) {
my $line= lc $subfield->[1];
$line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=/ /g;
foreach (split / /,$line) {
next unless $_;
# warn $record->as_formatted."$_ =>".$title;
if ($result{__RAW__}->{"$_"} =~ /$authid,$title\-(\d);/) {
my $weight=$1+1;
# $weight++;
$result{__RAW__}->{"$_"} =~ s/$authid,$title\-(\d);//;
$result{__RAW__}->{"$_"} .= "$authid,$title-$weight;";
} else {
$result{__RAW__}->{"$_"}.="$authid,$title-1;";
}
}
}
}
}
}
print "\nInserting...\n";
$i=0;
my $commitnum = 100;
$dbh->{AutoCommit} = 0;
$sth = $dbh->prepare("INSERT INTO nozebra (server,indexname,value,biblionumbers) VALUES ('authorityserver',?,?,?)");
foreach my $key (keys %result) {
foreach my $index (keys %{$result{$key}}) {
if (length($result{$key}->{$index}) > 1000000) {
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";
}
print "\r$i";
$i++;
$sth->execute($key,$index,$result{$key}->{$index});
$dbh->commit() if (0 == $i % $commitnum);
}
$dbh->commit() if (0 == $i % $commitnum);
}
$dbh->commit;
print "\nauthorities done\n";

View file

@ -656,9 +656,7 @@ sub print_usage {
$0: reindex MARC bibs and/or authorities in Zebra.
Use this batch job to reindex all biblio or authority
records in your Koha database. This job is useful
only if you are using Zebra; if you are using the 'NoZebra'
mode, this job should not be used.
records in your Koha database.
Parameters:
-b index bibliographic records

View file

@ -489,11 +489,6 @@ if ($tag) {
$results_hashref->{biblioserver}->{RECORDS} = \@marclist;
# FIXME: tag search and standard search should work together, not exclusively
# FIXME: No facets for tags search.
}
elsif (C4::Context->preference('NoZebra')) {
eval {
($error, $results_hashref, $facets) = NZgetRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$query_type,$scan);
};
} elsif ($build_grouped_results) {
eval {
($error, $results_hashref, $facets) = C4::Search::pazGetRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$query_type,$scan);
@ -668,7 +663,7 @@ for (my $i=0;$i<@servers;$i++) {
exit;
}
if ($hits) {
if (!C4::Context->preference('NoZebra') && !$build_grouped_results) {
if ( !$build_grouped_results ) {
# We build the encrypted list of first OPACnumSearchResults biblios to pass with the search criteria for paging on opac-detail
$pasarParams .= '&amp;listBiblios=';
my $j = 0;

View file

@ -40,9 +40,7 @@ $contextmodule->mock('_new_dbh', sub {
return $dbh });
$contextmodule->mock('preference', sub {
my ($self, $pref) = @_;
if ($pref eq 'NoZebra') {
return 0;
} elsif ($pref eq 'marcflavour') {
if ($pref eq 'marcflavour') {
return 'MARC21';
} elsif ($pref eq 'QueryStemming') {
return $QueryStemming;

View file

@ -144,7 +144,6 @@ sub startup_15_truncate_tables : Test( startup => 1 ) {
# matchpoint_components
# matchpoints
# notifys
# nozebra
# old_issues
# old_reserves
# opac_news
@ -203,7 +202,6 @@ sub startup_15_truncate_tables : Test( startup => 1 ) {
issuingrules
matchchecks
notifys
nozebra
old_issues
old_reserves
overduerules
@ -606,9 +604,6 @@ Useful for test routines that need to do a
lot of indexing without having to wait for
zebraqueue.
In NoZebra model, this only marks zebraqueue
done - the records should already be indexed.
=cut
sub reindex_marc {
@ -618,8 +613,6 @@ sub reindex_marc {
my $dbh = C4::Context->dbh();
$dbh->do("UPDATE zebraqueue SET done = 1 WHERE done = 0");
return if C4::Context->preference('NoZebra');
my $directory = tempdir(CLEANUP => 1);
foreach my $record_type qw(biblio authority) {
mkdir "$directory/$record_type";
@ -728,7 +721,6 @@ sub create_test_database {
my ($fwk_language, $installed_list) = $installer->load_sql_in_order($all_languages, @$list);
$installer->set_version_syspref();
$installer->set_marcflavour_syspref('MARC21');
$installer->set_indexing_engine(0);
diag 'database created.'
}

View file

@ -46,9 +46,6 @@ sub methods : Test( 1 ) {
get_koha_field_from_marc
TransformMarcToKohaOneField
ModZebra
GetNoZebraIndexes
_DelBiblioNoZebra
_AddBiblioNoZebra
_find_value
_koha_marc_update_bib_ids
_koha_marc_update_biblioitem_cn_sort

View file

@ -1,72 +0,0 @@
package KohaTest::Biblio::GetNoZebraIndexes;
use base qw( KohaTest::Biblio );
use strict;
use warnings;
use Test::More;
use C4::Biblio;
=head2 STARTUP METHODS
These get run once, before the main test methods in this module
=cut
=head2 TEST METHODS
standard test methods
=head3
=cut
sub returns_expected_hashref : Test(2) {
my $self = shift;
my %nzi = C4::Biblio::GetNoZebraIndexes();
ok( scalar keys %nzi, 'got some keys from GetNoZebraIndexes' );
my %expected = (
'title' => '130a,210a,222a,240a,243a,245a,245b,246a,246b,247a,247b,250a,250b,440a,830a',
'author' => '100a,100b,100c,100d,110a,111a,111b,111c,111d,245c,700a,710a,711a,800a,810a,811a',
'isbn' => '020a',
'issn' => '022a',
'lccn' => '010a',
'biblionumber' => '999c',
'itemtype' => '942c',
'publisher' => '260b',
'date' => '260c',
'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',
'subject' => '600*,610*,611*,630*,650*,651*,653*,654*,655*,662*,690*',
'dewey' => '082',
'bc' => '952p',
'callnum' => '952o',
'an' => '6009,6109,6119',
'homebranch' => '952a,952c'
);
is_deeply( \%nzi, \%expected, 'GetNoZebraIndexes returns the expected hashref' );
}
=head2 HELPER METHODS
These methods are used by other test methods, but
are not meant to be called directly.
=cut
=cut
=head2 SHUTDOWN METHODS
These get run once, after the main test methods in this module
=head3
=cut
1;

View file

@ -23,7 +23,6 @@ sub methods : Test( 1 ) {
load_db_schema
load_sql_in_order
set_marcflavour_syspref
set_indexing_engine
set_version_syspref
load_sql
);

View file

@ -23,12 +23,6 @@ sub methods : Test( 1 ) {
_build_weighted_query
buildQuery
searchResults
NZgetRecords
NZanalyse
NZoperatorAND
NZoperatorOR
NZoperatorNOT
NZorder
);
can_ok( $self->testing_class, @methods );

View file

@ -1,235 +0,0 @@
package KohaTest::Search::NoZebra;
use base qw( KohaTest::Search );
use strict;
use warnings;
use Test::More;
use MARC::Record;
use C4::Search;
use C4::Biblio;
use C4::Context;
=head2 STARTUP METHODS
These get run once, before the main test methods in this module
=cut
=head3 startup_50_init_nozebra
Turn on NoZebra mode, for now, assumes and requires
that the test database has started out using Zebra.
=cut
sub startup_50_init_nozebra : Test( startup => 3 ) {
my $using_nozebra = C4::Context->preference('NoZebra');
ok(!$using_nozebra, "starting out using Zebra");
my $dbh = C4::Context->dbh;
$dbh->do("UPDATE systempreferences SET value=1 WHERE variable='NoZebra'");
$dbh->do("UPDATE systempreferences SET value=0 WHERE variable in ('QueryFuzzy','QueryWeightFields','QueryStemming')");
C4::Context->clear_syspref_cache();
$using_nozebra = C4::Context->preference('NoZebra');
ok($using_nozebra, "switched to NoZebra");
my $sth = $dbh->prepare("SELECT COUNT(*) FROM nozebra");
$sth->execute;
my ($count) = $sth->fetchrow_array;
$sth->finish;
cmp_ok($count, '==', 0, "NoZebra index starts off empty");
}
sub startup_51_add_bibs : Test( startup => 2 ) {
my $self = shift;
my $bib1 = MARC::Record->new();
$bib1->leader(' nam a22 7a 4500');
$bib1->append_fields(
MARC::Field->new('010', ' ', ' ', a => 'lccn001'),
MARC::Field->new('020', ' ', ' ', a => 'isbn001'),
MARC::Field->new('022', ' ', ' ', a => 'issn001'),
MARC::Field->new('100', ' ', ' ', a => 'Cat, Felix T.'),
MARC::Field->new('245', ' ', ' ', a => 'Of mice and men :', b=> 'a history'),
);
my $bib2 = MARC::Record->new();
$bib2->leader(' nam a22 7a 4500');
$bib2->append_fields(
MARC::Field->new('010', ' ', ' ', a => 'lccn002'),
MARC::Field->new('020', ' ', ' ', a => 'isbn002'),
MARC::Field->new('022', ' ', ' ', a => 'issn002'),
MARC::Field->new('100', ' ', ' ', a => 'Dog, Rover T.'),
MARC::Field->new('245', ' ', ' ', a => 'Of mice and men :', b=> 'a digression'),
);
my $dbh = C4::Context->dbh;
my $count_sth = $dbh->prepare("SELECT COUNT(*) FROM nozebra");
my $count;
my ($bib1_bibnum, $bib1_bibitemnum) = AddBiblio($bib1, '');
$count_sth->execute;
($count) = $count_sth->fetchrow_array;
cmp_ok($count, '==', 14, "correct number of new words indexed"); # tokens + biblionumber + __RAW__
my ($bib2_bibnum, $bib2_bibitemnum) = AddBiblio($bib2, '');
$count_sth->execute;
($count) = $count_sth->fetchrow_array;
cmp_ok($count, '==', 22, "correct number of new words indexed"); # tokens + biblionumber + __RAW__
push @{ $self->{nozebra_test_bibs} }, $bib1_bibnum, $bib2_bibnum;
}
=head2 TEST METHODS
Standard test methods
=cut
sub basic_searches_via_nzanalyze : Test( 28 ) {
my $self = shift;
my ($bib1_bibnum, $bib2_bibnum) = @{ $self->{nozebra_test_bibs} };
my $results = C4::Search::NZanalyse('foobar');
ok(!defined($results), "no hits on 'foobar'");
$results = C4::Search::NZanalyse('dog');
my ($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 1, "one hit on 'dog'");
is($bib2_bibnum, $bibnumbers[0], "correct hit on 'dog'");
$results = C4::Search::NZanalyse('au=dog');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 1, "one hit on 'au=dog'");
is($bib2_bibnum, $bibnumbers[0], "correct hit on 'au=dog'");
$results = C4::Search::NZanalyse('isbn=dog');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 0, "zero hits on 'isbn=dog'");
$results = C4::Search::NZanalyse('cat');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 1, "one hit on 'cat'");
is($bib1_bibnum, $bibnumbers[0], "correct hit on 'cat'");
$results = C4::Search::NZanalyse('cat and dog');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 0, "zero hits on 'cat and dog'");
$results = C4::Search::NZanalyse('cat or dog');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 2, "two hits on 'cat or dog'");
is_deeply([ sort @bibnumbers ], [ sort($bib1_bibnum, $bib2_bibnum) ], "correct hits on 'cat or dog'");
$results = C4::Search::NZanalyse('mice and men');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 2, "two hits on 'mice and men'");
is_deeply([ sort @bibnumbers ], [ sort($bib1_bibnum, $bib2_bibnum) ], "correct hits on 'mice and men'");
$results = C4::Search::NZanalyse('title=digression or issn=issn001');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 2, "two hits on 'title=digression or issn=issn001'");
is_deeply([ sort @bibnumbers ], [ sort($bib1_bibnum, $bib2_bibnum) ], "correct hits on 'title=digression or issn=issn001'");
$results = C4::Search::NZanalyse('title=digression and issn=issn002');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 1, "two hits on 'title=digression and issn=issn002'");
is($bib2_bibnum, $bibnumbers[0], "correct hit on 'title=digression and issn=issn002'");
$results = C4::Search::NZanalyse('mice not men');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 0, "zero hits on 'mice not men'");
$results = C4::Search::NZanalyse('mice not dog');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 1, "one hit on 'mice not dog'");
is($bib1_bibnum, $bibnumbers[0], "correct hit on 'mice not dog'");
$results = C4::Search::NZanalyse('isbn > a');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 2, "two hits on 'isbn > a'");
is_deeply([ sort @bibnumbers ], [ sort($bib1_bibnum, $bib2_bibnum) ], "correct hits on 'isbn > a'");
$results = C4::Search::NZanalyse('isbn < z');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 2, "two hits on 'isbn < z'");
is_deeply([ sort @bibnumbers ], [ sort($bib1_bibnum, $bib2_bibnum) ], "correct hits on 'isbn < z'");
$results = C4::Search::NZanalyse('isbn > isbn001');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 1, "one hit on 'isbn > isbn001'");
is($bib2_bibnum, $bibnumbers[0], "correct hit on 'isbn > isbn001'");
$results = C4::Search::NZanalyse('isbn>=isbn001');
($hits, @bibnumbers) = parse_nzanalyse($results);
cmp_ok($hits, '==', 2, "two hits on 'isbn>=isbn001'");
is_deeply([ sort @bibnumbers ], [ sort($bib1_bibnum, $bib2_bibnum) ], "correct hits on 'isbn>=isbn001'");
}
sub parse_nzanalyse {
my $results = shift;
my @bibnumbers = ();
if (defined $results) {
# NZanalyze currently has a funky way of returning results -
# it does not guarantee that a biblionumber occurs only
# once in the results string. Hence we must remove
# duplicates, like NZorder (inefficently) does
my %hash;
@bibnumbers = grep { ++$hash{$_} == 1 } map { my @f = split /,/, $_; $f[0]; } split /;/, $results;
}
return scalar(@bibnumbers), @bibnumbers;
}
=head2 SHUTDOWN METHODS
These get run once, after all of the main tests methods in this module
=cut
sub shutdown_49_remove_bibs : Test( shutdown => 4 ) {
my $self = shift;
my ($bib1_bibnum, $bib2_bibnum) = @{ $self->{nozebra_test_bibs} };
my $dbh = C4::Context->dbh;
my $count_sth = $dbh->prepare("SELECT COUNT(*) FROM nozebra");
my $count;
my $error = DelBiblio($bib2_bibnum);
ok(!defined($error), "deleted bib $bib2_bibnum");
$count_sth->execute;
($count) = $count_sth->fetchrow_array;
TODO: { local $TODO = 'nothing actually gets deleted from nozebra currently';
cmp_ok($count, '==', 14, "correct number of words indexed after bib $bib2_bibnum deleted");
}
$error = DelBiblio($bib1_bibnum);
ok(!defined($error), "deleted bib $bib1_bibnum");
$count_sth->execute;
($count) = $count_sth->fetchrow_array;
TODO: { local $TODO = 'nothing actually gets deleted from nozebra currently';
cmp_ok($count, '==', 0, "no entries left in nozebra after bib $bib1_bibnum deleted");
}
delete $self->{nozebra_test_bibs};
}
sub shutdown_50_init_nozebra : Test( shutdown => 3 ) {
my $using_nozebra = C4::Context->preference('NoZebra');
ok($using_nozebra, "still in NoZebra mode");
my $dbh = C4::Context->dbh;
$dbh->do("UPDATE systempreferences SET value=0 WHERE variable='NoZebra'");
$dbh->do("UPDATE systempreferences SET value=1 WHERE variable in ('QueryFuzzy','QueryWeightFields','QueryStemming')");
C4::Context->clear_syspref_cache();
$using_nozebra = C4::Context->preference('NoZebra');
ok(!$using_nozebra, "switched to Zebra");
# FIXME
$dbh->do("DELETE FROM nozebra");
my $sth = $dbh->prepare("SELECT COUNT(*) FROM nozebra");
$sth->execute;
my ($count) = $sth->fetchrow_array;
$sth->finish;
cmp_ok($count, '==', 0, "NoZebra index finishes up empty");
}
1;