3 # Copyright 2000-2002 Katipo Communications
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA 02111-1307 USA
25 use MARC::File::USMARC;
28 use vars qw($VERSION @ISA @EXPORT);
30 # set the version for version checking
36 # don't forget MARCxxx subs are exported only for testing purposes. Should not be used
37 # as the old-style API and the NEW one are the only public functions.
40 &updateBiblio &updateBiblioItem &updateItem
41 &itemcount &newbiblio &newbiblioitem
42 &modnote &newsubject &newsubtitle
43 &modbiblio &checkitems
45 &modsubtitle &modsubject &modaddauthor &moditem &countitems
46 &delitem &deletebiblioitem &delbiblio
48 &getbiblioitembybiblionumber
49 &getbiblioitem &getitemsbybiblioitem
51 &newcompletebiblioitem
53 &MARCfind_oldbiblionumber_from_MARCbibid
54 &MARCfind_MARCbibid_from_oldbiblionumber
55 &MARCfind_marc_from_kohafield
57 &MARCfind_frameworkcode
60 &NEWnewbiblio &NEWnewitem
61 &NEWmodbiblio &NEWmoditem
62 &NEWdelbiblio &NEWdelitem
63 &NEWmodbiblioframework
65 &MARCaddbiblio &MARCadditem
66 &MARCmodsubfield &MARCaddsubfield
67 &MARCmodbiblio &MARCmoditem
68 &MARCkoha2marcBiblio &MARCmarc2koha
69 &MARCkoha2marcItem &MARChtml2marc
70 &MARCgetbiblio &MARCgetitem
71 &MARCaddword &MARCdelword
81 # MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC
84 # all the following subs takes a MARC::Record as parameter and manage
85 # the MARC-DB. They are called by the 1.0/1.2 xxx subs, and by the
86 # NEWxxx subs (xxx deals with old-DB parameters, the NEWxxx deals with MARC-DB parameter)
90 C4::Biblio - acquisition, catalog management functions
94 move from 1.2 to 1.4 version :
95 1.2 and previous version uses a specific API to manage biblios. This API uses old-DB style parameters.
96 In the 1.4 version, we want to do 2 differents things :
97 - keep populating the old-DB, that has a LOT less datas than MARC
98 - populate the MARC-DB
99 To populate the DBs we have 2 differents sources :
100 - the standard acquisition system (through book sellers), that does'nt use MARC data
101 - the MARC acquisition system, that uses MARC data.
103 Thus, we have 2 differents cases :
104 - with the standard acquisition system, we have non MARC data and want to populate old-DB and MARC-DB, knowing it's an incomplete MARC-record
105 - with the MARC acquisition system, we have MARC datas, and want to loose nothing in MARC-DB. So, we can't store datas in old-DB, then copy in MARC-DB. we MUST have an API for true MARC data, that populate MARC-DB then old-DB
107 That's why we need 4 subs :
108 all I<subs beginning by MARC> manage only MARC tables. They manage MARC-DB with MARC::Record parameters
109 all I<subs beginning by OLD> manage only OLD-DB tables. They manage old-DB with old-DB parameters
110 all I<subs beginning by NEW> manage both OLD-DB and MARC tables. They use MARC::Record as parameters. it's the API that MUST be used in MARC acquisition system
111 all I<subs beginning by seomething else> are the old-style API. They use old-DB as parameter, then call internally the OLD and MARC subs.
113 - NEW and old-style API should be used in koha to manage biblio
114 - MARCsubs are divided in 2 parts :
115 * some of them manage MARC parameters. They are heavily used in koha.
116 * some of them manage MARC biblio : they are mostly used by NEW and old-style subs.
117 - OLD are used internally only
119 all subs requires/use $dbh as 1st parameter.
121 I<NEWxxx related subs>
123 all subs requires/use $dbh as 1st parameter.
124 those subs are used by the MARC-compliant version of koha : marc import, or marc management.
126 I<OLDxxx related subs>
128 all subs requires/use $dbh as 1st parameter.
129 those subs are used by the MARC-compliant version of koha : marc import, or marc management.
131 They all are the exact copy of 1.0/1.2 version of the sub without the OLD.
132 The OLDxxx is called by the original xxx sub.
133 the 1.4 xxx sub also builds MARC::Record an calls the MARCxxx
135 WARNING : there is 1 difference between initialxxx and OLDxxx :
136 the db header $dbh is always passed as parameter to avoid over-DB connexion
142 =item @tagslib = &MARCgettagslib($dbh,1|0,$itemtype);
144 last param is 1 for liblibrarian and 0 for libopac
145 $itemtype contains the itemtype framework reference. If empty or does not exist, the default one is used
146 returns a hash with tag/subfield meaning
147 =item ($tagfield,$tagsubfield) = &MARCfind_marc_from_kohafield($dbh,$kohafield);
149 finds MARC tag and subfield for a given kohafield
150 kohafield is "table.field" where table= biblio|biblioitems|items, and field a field of the previous table
152 =item $biblionumber = &MARCfind_oldbiblionumber_from_MARCbibid($dbh,$MARCbibi);
154 finds a old-db biblio number for a given MARCbibid number
156 =item $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$oldbiblionumber);
158 finds a MARC bibid from a old-db biblionumber
160 =item $MARCRecord = &MARCkoha2marcBiblio($dbh,$biblionumber,biblioitemnumber);
162 MARCkoha2marcBiblio is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB biblio/biblioitem
164 =item $MARCRecord = &MARCkoha2marcItem($dbh,$biblionumber,itemnumber);
166 MARCkoha2marcItem is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB item
168 =item $MARCRecord = &MARCkoha2marcSubtitle($dbh,$biblionumber,$subtitle);
170 MARCkoha2marcSubtitle is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB subtitle
172 =item $olddb = &MARCmarc2koha($dbh,$MARCRecord);
174 builds a hash with old-db datas from a MARC::Record
176 =item &MARCaddbiblio($dbh,$MARC::Record,$biblionumber);
178 creates a biblio (in the MARC tables only). $biblionumber is the old-db biblionumber of the biblio
180 =item &MARCaddsubfield($dbh,$bibid,$tagid,$indicator,$tagorder,$subfieldcode,$subfieldorder,$subfieldvalue);
182 adds a subfield in a biblio (in the MARC tables only).
184 =item $MARCRecord = &MARCgetbiblio($dbh,$bibid);
186 Returns a MARC::Record for the biblio $bibid.
188 =item &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,$delete);
190 MARCmodbiblio changes a biblio for a biblio,MARC::Record passed as parameter
191 It 1st delete the biblio, then recreates it.
192 WARNING : the $delete parameter is not used anymore (too much unsolvable cases).
193 =item ($subfieldid,$subfieldvalue) = &MARCmodsubfield($dbh,$subfieldid,$subfieldvalue);
195 MARCmodsubfield changes the value of a given subfield
197 =item $subfieldid = &MARCfindsubfield($dbh,$bibid,$tag,$subfieldcode,$subfieldorder,$subfieldvalue);
199 MARCfindsubfield returns a subfield number given a bibid/tag/subfieldvalue values.
200 Returns -1 if more than 1 answer
202 =item $subfieldid = &MARCfindsubfieldid($dbh,$bibid,$tag,$tagorder,$subfield,$subfieldorder);
204 MARCfindsubfieldid find a subfieldid for a bibid/tag/tagorder/subfield/subfieldorder
206 =item &MARCdelsubfield($dbh,$bibid,$tag,$tagorder,$subfield,$subfieldorder);
208 MARCdelsubfield delete a subfield for a bibid/tag/tagorder/subfield/subfieldorder
209 If $subfieldorder is not set, delete all the $tag$subfield subfields
211 =item &MARCdelbiblio($dbh,$bibid);
213 MARCdelbiblio delete biblio $bibid
215 =item &MARCkoha2marcOnefield
217 used by MARCkoha2marc and should not be useful elsewhere
219 =item &MARCmarc2kohaOnefield
221 used by MARCmarc2koha and should not be useful elsewhere
225 used to manage MARC_word table and should not be useful elsewhere
229 used to manage MARC_word table and should not be useful elsewhere
234 my ( $dbh, $forlibrarian, $frameworkcode ) = @_;
235 $frameworkcode = "" unless $frameworkcode;
237 my $libfield = ( $forlibrarian eq 1 ) ? 'liblibrarian' : 'libopac';
239 # check that framework exists
242 "select count(*) from marc_tag_structure where frameworkcode=?");
243 $sth->execute($frameworkcode);
244 my ($total) = $sth->fetchrow;
245 $frameworkcode = "" unless ( $total > 0 );
248 "select tagfield,liblibrarian,libopac,mandatory,repeatable from marc_tag_structure where frameworkcode=? order by tagfield"
250 $sth->execute($frameworkcode);
251 my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable );
253 while ( ( $tag, $liblibrarian, $libopac, $mandatory, $repeatable ) = $sth->fetchrow ) {
254 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
255 $res->{$tab}->{tab} = ""; # XXX
256 $res->{$tag}->{mandatory} = $mandatory;
257 $res->{$tag}->{repeatable} = $repeatable;
262 "select tagfield,tagsubfield,liblibrarian,libopac,tab, mandatory, repeatable,authorised_value,authtypecode,value_builder,kohafield,seealso,hidden,isurl,link from marc_subfield_structure where frameworkcode=? order by tagfield,tagsubfield"
264 $sth->execute($frameworkcode);
267 my $authorised_value;
277 ( $tag, $subfield, $liblibrarian, , $libopac, $tab,
278 $mandatory, $repeatable, $authorised_value, $authtypecode,
279 $value_builder, $kohafield, $seealso, $hidden,
284 $res->{$tag}->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
285 $res->{$tag}->{$subfield}->{tab} = $tab;
286 $res->{$tag}->{$subfield}->{mandatory} = $mandatory;
287 $res->{$tag}->{$subfield}->{repeatable} = $repeatable;
288 $res->{$tag}->{$subfield}->{authorised_value} = $authorised_value;
289 $res->{$tag}->{$subfield}->{authtypecode} = $authtypecode;
290 $res->{$tag}->{$subfield}->{value_builder} = $value_builder;
291 $res->{$tag}->{$subfield}->{kohafield} = $kohafield;
292 $res->{$tag}->{$subfield}->{seealso} = $seealso;
293 $res->{$tag}->{$subfield}->{hidden} = $hidden;
294 $res->{$tag}->{$subfield}->{isurl} = $isurl;
295 $res->{$tag}->{$subfield}->{link} = $link;
300 sub MARCfind_marc_from_kohafield {
301 my ( $dbh, $kohafield,$frameworkcode ) = @_;
302 return 0, 0 unless $kohafield;
303 my $relations = C4::Context->marcfromkohafield;
304 return ($relations->{$frameworkcode}->{$kohafield}->[0],$relations->{$frameworkcode}->{$kohafield}->[1]);
307 sub MARCfind_oldbiblionumber_from_MARCbibid {
308 my ( $dbh, $MARCbibid ) = @_;
310 $dbh->prepare("select biblionumber from marc_biblio where bibid=?");
311 $sth->execute($MARCbibid);
312 my ($biblionumber) = $sth->fetchrow;
313 return $biblionumber;
316 sub MARCfind_MARCbibid_from_oldbiblionumber {
317 my ( $dbh, $oldbiblionumber ) = @_;
319 $dbh->prepare("select bibid from marc_biblio where biblionumber=?");
320 $sth->execute($oldbiblionumber);
321 my ($bibid) = $sth->fetchrow;
327 # pass the MARC::Record to this function, and it will create the records in the marc tables
328 my ($dbh,$record,$biblionumber,$frameworkcode,$bibid) = @_;
329 my @fields=$record->fields();
331 # adding main table, and retrieving bibid
332 # if bibid is sent, then it's not a true add, it's only a re-add, after a delete (ie, a mod)
333 # if bibid empty => true add, find a new bibid number
336 "lock tables marc_biblio WRITE,marc_subfield_table WRITE, marc_word WRITE, marc_blob_subfield WRITE, stopwords READ"
340 "insert into marc_biblio (datecreated,biblionumber,frameworkcode) values (now(),?,?)"
342 $sth->execute( $biblionumber, $frameworkcode );
343 $sth = $dbh->prepare("select max(bibid) from marc_biblio");
345 ($bibid) = $sth->fetchrow;
350 # now, add subfields...
351 foreach my $field (@fields) {
353 if ( $field->tag() < 10 ) {
354 &MARCaddsubfield( $dbh, $bibid, $field->tag(), '', $fieldcount, '',
358 my @subfields = $field->subfields();
359 foreach my $subfieldcount ( 0 .. $#subfields ) {
364 $field->indicator(1) . $field->indicator(2),
366 $subfields[$subfieldcount][0],
368 $subfields[$subfieldcount][1]
374 &MARCaddsubfield($dbh,$bibid,'000','',$fieldcount+1,'',1,$record->leader);
375 $dbh->do("unlock tables");
381 # pass the MARC::Record to this function, and it will create the records in the marc tables
382 my ($dbh,$record,$biblionumber) = @_;
383 # search for MARC biblionumber
384 $dbh->do("lock tables marc_biblio WRITE,marc_subfield_table WRITE, marc_word WRITE, marc_blob_subfield WRITE, stopwords READ");
385 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
386 my @fields=$record->fields();
387 my $sth = $dbh->prepare("select max(tagorder) from marc_subfield_table where bibid=?");
388 $sth->execute($bibid);
389 my ($fieldcount) = $sth->fetchrow;
391 # now, add subfields...
392 foreach my $field (@fields) {
393 my @subfields = $field->subfields();
395 foreach my $subfieldcount ( 0 .. $#subfields ) {
400 $field->indicator(1) . $field->indicator(2),
402 $subfields[$subfieldcount][0],
404 $subfields[$subfieldcount][1]
408 $dbh->do("unlock tables");
412 sub MARCaddsubfield {
414 # Add a new subfield to a tag into the DB.
416 $dbh, $bibid, $tagid, $tag_indicator,
417 $tagorder, $subfieldcode, $subfieldorder, $subfieldvalues
420 return unless $subfieldvalues;
421 # warn "$tagid / $subfieldcode / $subfieldvalues";
422 # if not value, end of job, we do nothing
423 # if ( length($subfieldvalues) == 0 ) {
426 if ( not($subfieldcode) ) {
429 my @subfieldvalues = split /\||#/, $subfieldvalues;
430 foreach my $subfieldvalue (@subfieldvalues) {
431 if ( length($subfieldvalue) > 255 ) {
433 "lock tables marc_blob_subfield WRITE, marc_subfield_table WRITE"
437 "insert into marc_blob_subfield (subfieldvalue) values (?)");
438 $sth->execute($subfieldvalue);
440 $dbh->prepare("select max(blobidlink)from marc_blob_subfield");
442 my ($res) = $sth->fetchrow;
445 "insert into marc_subfield_table (bibid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,valuebloblink) values (?,?,?,?,?,?,?)"
447 $sth->execute( $bibid, ( sprintf "%03s", $tagid ), $tagorder,
448 $tag_indicator, $subfieldcode, $subfieldorder, $res );
450 if ( $sth->errstr ) {
452 "ERROR ==> insert into marc_subfield_table (bibid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue) values ($bibid,$tagid,$tagorder,$tag_indicator,$subfieldcode,$subfieldorder,$subfieldvalue)\n";
454 $dbh->do("unlock tables");
459 "insert into marc_subfield_table (bibid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue) values (?,?,?,?,?,?,?)"
462 $bibid, ( sprintf "%03s", $tagid ),
463 $tagorder, $tag_indicator,
464 $subfieldcode, $subfieldorder,
467 if ( $sth->errstr ) {
469 "ERROR ==> insert into marc_subfield_table (bibid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue) values ($bibid,$tagid,$tagorder,$tag_indicator,$subfieldcode,$subfieldorder,$subfieldvalue)\n";
473 $dbh, $bibid, $tagid, $tagorder,
474 $subfieldcode, $subfieldorder, $subfieldvalue
481 # Returns MARC::Record of the biblio passed in parameter.
482 my ( $dbh, $biblionumber ) = @_;
483 my $sth = $dbh->prepare('select marc from biblioitems where biblionumber=?');
484 $sth->execute($biblionumber);
485 my ($marc) = $sth->fetchrow;
486 my $record = MARC::File::USMARC::decode($marc);
492 # Returns MARC::Record of the biblio passed in parameter.
493 my ( $dbh, $bibid, $itemnumber ) = @_;
494 my $record = MARC::Record->new();
496 # search MARC tagorder
499 "select tagorder from marc_subfield_table,marc_subfield_structure where marc_subfield_table.tag=marc_subfield_structure.tagfield and marc_subfield_table.subfieldcode=marc_subfield_structure.tagsubfield and bibid=? and kohafield='items.itemnumber' and subfieldvalue=?"
501 $sth2->execute( $bibid, $itemnumber );
502 my ($tagorder) = $sth2->fetchrow_array();
504 #---- TODO : the leader is missing
507 "select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
508 from marc_subfield_table
509 where bibid=? and tagorder=? order by subfieldcode,subfieldorder
514 "select subfieldvalue from marc_blob_subfield where blobidlink=?");
515 $sth->execute( $bibid, $tagorder );
516 while ( my $row = $sth->fetchrow_hashref ) {
517 if ( $row->{'valuebloblink'} ) { #---- search blob if there is one
518 $sth2->execute( $row->{'valuebloblink'} );
519 my $row2 = $sth2->fetchrow_hashref;
521 $row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
523 if ( $record->field( $row->{'tag'} ) ) {
526 #--- this test must stay as this, because of strange behaviour of mySQL/Perl DBI with char var containing a number...
527 #--- sometimes, eliminates 0 at beginning, sometimes no ;-\\\
528 if ( length( $row->{'tag'} ) < 3 ) {
529 $row->{'tag'} = "0" . $row->{'tag'};
531 $field = $record->field( $row->{'tag'} );
534 $field->add_subfields( $row->{'subfieldcode'},
535 $row->{'subfieldvalue'} );
536 $record->delete_field($field);
537 $record->add_fields($field);
541 if ( length( $row->{'tag'} ) < 3 ) {
542 $row->{'tag'} = "0" . $row->{'tag'};
545 MARC::Field->new( $row->{'tag'}, " ", " ",
546 $row->{'subfieldcode'} => $row->{'subfieldvalue'} );
547 $record->add_fields($temp);
555 my ($dbh,$bibid,$record,$frameworkcode,$delete)=@_;
556 # 1st delete the biblio,
558 my $biblionumber = MARCfind_oldbiblionumber_from_MARCbibid($dbh,$bibid);
559 &MARCdelbiblio($dbh,$bibid,1);
560 &MARCaddbiblio($dbh,$record,$biblionumber,$frameworkcode,$bibid);
564 my ( $dbh, $bibid, $keep_items ) = @_;
566 # if the keep_item is set to 1, then all items are preserved.
567 # This flag is set when the delbiblio is called by modbiblio
568 # due to a too complex structure of MARC (repeatable fields and subfields),
569 # the best solution for a modif is to delete / recreate the record.
571 # 1st of all, copy the MARC::Record to deletedbiblio table => if a true deletion, MARC data will be kept.
572 # if deletion called before MARCmodbiblio => won't do anything, as the oldbiblionumber doesn't
573 # exist in deletedbiblio table
574 my $record = MARCgetbiblio( $dbh, $bibid );
575 my $oldbiblionumber =
576 MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
578 $dbh->prepare("update deletedbiblio set marc=? where biblionumber=?");
579 $copy2deleted->execute( $record->as_usmarc(), $oldbiblionumber );
581 # now, delete in MARC tables.
582 if ( $keep_items eq 1 ) {
584 #search item field code
587 "select tagfield from marc_subfield_structure where kohafield like 'items.%'"
590 my $itemtag = $sth->fetchrow_hashref->{tagfield};
592 "delete from marc_subfield_table where bibid=$bibid and tag<>$itemtag"
595 "delete from marc_word where bibid=$bibid and not (tagsubfield like \"$itemtag%\")"
599 $dbh->do("delete from marc_biblio where bibid=$bibid");
600 $dbh->do("delete from marc_subfield_table where bibid=$bibid");
601 $dbh->do("delete from marc_word where bibid=$bibid");
607 # delete the item passed in parameter in MARC tables.
608 my ( $dbh, $bibid, $itemnumber ) = @_;
610 # my $record = MARC::Record->new();
611 # search MARC tagorder
612 my $record = MARCgetitem( $dbh, $bibid, $itemnumber );
614 $dbh->prepare("update deleteditems set marc=? where itemnumber=?");
615 $copy2deleted->execute( $record->as_usmarc(), $itemnumber );
619 "select tagorder from marc_subfield_table,marc_subfield_structure where marc_subfield_table.tag=marc_subfield_structure.tagfield and marc_subfield_table.subfieldcode=marc_subfield_structure.tagsubfield and bibid=? and kohafield='items.itemnumber' and subfieldvalue=?"
621 $sth2->execute( $bibid, $itemnumber );
622 my ($tagorder) = $sth2->fetchrow_array();
625 "delete from marc_subfield_table where bibid=? and tagorder=?");
626 $sth->execute( $bibid, $tagorder );
630 my ($dbh,$record,$bibid,$itemnumber,$delete)=@_;
631 my $biblionumber = MARCfind_oldbiblionumber_from_MARCbibid($dbh,$bibid);
632 &MARCdelitem($dbh,$bibid,$itemnumber);
633 &MARCadditem($dbh,$record,$biblionumber);
636 sub MARCmodsubfield {
638 # Subroutine changes a subfield value given a subfieldid.
639 my ( $dbh, $subfieldid, $subfieldvalue ) = @_;
640 $dbh->do("lock tables marc_blob_subfield WRITE,marc_subfield_table WRITE");
643 "select valuebloblink from marc_subfield_table where subfieldid=?");
644 $sth1->execute($subfieldid);
645 my ($oldvaluebloblink) = $sth1->fetchrow;
649 # if too long, use a bloblink
650 if ( length($subfieldvalue) > 255 ) {
652 # if already a bloblink, update it, otherwise, insert a new one.
653 if ($oldvaluebloblink) {
656 "update marc_blob_subfield set subfieldvalue=? where blobidlink=?"
658 $sth->execute( $subfieldvalue, $oldvaluebloblink );
663 "insert into marc_blob_subfield (subfieldvalue) values (?)");
664 $sth->execute($subfieldvalue);
666 $dbh->prepare("select max(blobidlink) from marc_blob_subfield");
668 my ($res) = $sth->fetchrow;
671 "update marc_subfield_table set subfieldvalue=null, valuebloblink=? where subfieldid=?"
673 $sth->execute( $res, $subfieldid );
678 # note this can leave orphan bloblink. Not a big problem, but we should build somewhere a orphan deleting script...
681 "update marc_subfield_table set subfieldvalue=?,valuebloblink=null where subfieldid=?"
683 $sth->execute( $subfieldvalue, $subfieldid );
685 $dbh->do("unlock tables");
689 "select bibid,tag,tagorder,subfieldcode,subfieldid,subfieldorder from marc_subfield_table where subfieldid=?"
691 $sth->execute($subfieldid);
692 my ( $bibid, $tagid, $tagorder, $subfieldcode, $x, $subfieldorder ) =
695 &MARCdelword( $dbh, $bibid, $tagid, $tagorder, $subfieldcode,
698 $dbh, $bibid, $tagid, $tagorder,
699 $subfieldcode, $subfieldorder, $subfieldvalue
701 return ( $subfieldid, $subfieldvalue );
704 sub MARCfindsubfield {
705 my ( $dbh, $bibid, $tag, $subfieldcode, $subfieldorder, $subfieldvalue ) =
707 my $resultcounter = 0;
711 "select subfieldid from marc_subfield_table where bibid=? and tag=? and subfieldcode=?";
712 my @bind_values = ( $bibid, $tag, $subfieldcode );
713 if ($subfieldvalue) {
714 $query .= " and subfieldvalue=?";
715 push ( @bind_values, $subfieldvalue );
718 if ( $subfieldorder < 1 ) {
721 $query .= " and subfieldorder=?";
722 push ( @bind_values, $subfieldorder );
724 my $sti = $dbh->prepare($query);
725 $sti->execute(@bind_values);
726 while ( ($subfieldid) = $sti->fetchrow ) {
728 $lastsubfieldid = $subfieldid;
730 if ( $resultcounter > 1 ) {
732 # Error condition. Values given did not resolve into a unique record. Don't know what to edit
733 # should rarely occur (only if we use subfieldvalue with a value that exists twice, which is strange)
737 return $lastsubfieldid;
741 sub MARCfindsubfieldid {
742 my ( $dbh, $bibid, $tag, $tagorder, $subfield, $subfieldorder ) = @_;
743 my $sth = $dbh->prepare( "select subfieldid from marc_subfield_table
744 where bibid=? and tag=? and tagorder=?
745 and subfieldcode=? and subfieldorder=?"
747 $sth->execute( $bibid, $tag, $tagorder, $subfield, $subfieldorder );
748 my ($res) = $sth->fetchrow;
750 $sth = $dbh->prepare( "select subfieldid from marc_subfield_table
751 where bibid=? and tag=? and tagorder=?
754 $sth->execute( $bibid, $tag, $tagorder, $subfield );
755 ($res) = $sth->fetchrow;
760 sub MARCfind_frameworkcode {
761 my ( $dbh, $biblionumber ) = @_;
763 $dbh->prepare("select frameworkcode from biblio where biblionumber=?");
764 $sth->execute($biblionumber);
765 my ($frameworkcode) = $sth->fetchrow;
766 return $frameworkcode;
769 sub MARCdelsubfield {
771 # delete a subfield for $bibid / tag / tagorder / subfield / subfieldorder
772 my ( $dbh, $bibid, $tag, $tagorder, $subfield, $subfieldorder ) = @_;
773 if ($subfieldorder) {
774 $dbh->do( "delete from marc_subfield_table where bibid='$bibid' and
775 tag='$tag' and tagorder='$tagorder'
776 and subfieldcode='$subfield' and subfieldorder='$subfieldorder'
779 $dbh->do( "delete from marc_word where bibid='$bibid' and
780 tagsubfield='$tag$subfield' and tagorder='$tagorder'
781 and subfieldorder='$subfieldorder'
785 $dbh->do( "delete from marc_subfield_table where bibid='$bibid' and
786 tag='$tag' and tagorder='$tagorder'
787 and subfieldcode='$subfield'"
789 $dbh->do( "delete from marc_word where bibid='$bibid' and
790 tagsubfield='$tag$subfield' and tagorder='$tagorder'"
795 sub MARCkoha2marcBiblio {
797 # this function builds partial MARC::Record from the old koha-DB fields
798 my ( $dbh, $biblionumber, $biblioitemnumber ) = @_;
801 "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
803 my $record = MARC::Record->new();
805 #--- if bibid, then retrieve old-style koha data
806 if ( $biblionumber > 0 ) {
809 "select biblionumber,author,title,unititle,notes,abstract,serial,seriestitle,copyrightdate,timestamp
810 from biblio where biblionumber=?"
812 $sth2->execute($biblionumber);
813 my $row = $sth2->fetchrow_hashref;
815 foreach $code ( keys %$row ) {
816 if ( $row->{$code} ) {
817 &MARCkoha2marcOnefield( $sth, $record, "biblio." . $code,
823 #--- if biblioitem, then retrieve old-style koha data
824 if ( $biblioitemnumber > 0 ) {
827 " SELECT biblioitemnumber,biblionumber,volume,number,classification,
828 itemtype,url,isbn,issn,dewey,subclass,publicationyear,publishercode,
829 volumedate,volumeddesc,timestamp,illus,pages,notes AS bnotes,size,place
831 WHERE biblioitemnumber=?
834 $sth2->execute($biblioitemnumber);
835 my $row = $sth2->fetchrow_hashref;
837 foreach $code ( keys %$row ) {
838 if ( $row->{$code} ) {
839 &MARCkoha2marcOnefield( $sth, $record, "biblioitems." . $code,
845 # other fields => additional authors, subjects, subtitles
848 " SELECT author FROM additionalauthors WHERE biblionumber=?");
849 $sth2->execute($biblionumber);
850 while ( my $row = $sth2->fetchrow_hashref ) {
851 &MARCkoha2marcOnefield( $sth, $record, "additionalauthors.author",
852 $row->{'author'},'' );
855 $dbh->prepare(" SELECT subject FROM bibliosubject WHERE biblionumber=?");
856 $sth2->execute($biblionumber);
857 while ( my $row = $sth2->fetchrow_hashref ) {
858 &MARCkoha2marcOnefield( $sth, $record, "bibliosubject.subject",
859 $row->{'subject'},'' );
863 " SELECT subtitle FROM bibliosubtitle WHERE biblionumber=?");
864 $sth2->execute($biblionumber);
865 while ( my $row = $sth2->fetchrow_hashref ) {
866 &MARCkoha2marcOnefield( $sth, $record, "bibliosubtitle.subtitle",
867 $row->{'subtitle'},'' );
872 sub MARCkoha2marcItem {
874 # this function builds partial MARC::Record from the old koha-DB fields
875 my ( $dbh, $biblionumber, $itemnumber ) = @_;
877 # my $dbh=&C4Connect;
880 "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
882 my $record = MARC::Record->new();
884 #--- if item, then retrieve old-style koha data
885 if ( $itemnumber > 0 ) {
887 # print STDERR "prepare $biblionumber,$itemnumber\n";
890 "SELECT itemnumber,biblionumber,multivolumepart,biblioitemnumber,barcode,dateaccessioned,
891 booksellerid,homebranch,price,replacementprice,replacementpricedate,datelastborrowed,
892 datelastseen,multivolume,stack,notforloan,itemlost,wthdrawn,itemcallnumber,issues,renewals,
893 reserves,restricted,binding,itemnotes,holdingbranch,timestamp
897 $sth2->execute($itemnumber);
898 my $row = $sth2->fetchrow_hashref;
900 foreach $code ( keys %$row ) {
901 if ( $row->{$code} ) {
902 &MARCkoha2marcOnefield( $sth, $record, "items." . $code,
910 sub MARCkoha2marcSubtitle {
912 # this function builds partial MARC::Record from the old koha-DB fields
913 my ( $dbh, $bibnum, $subtitle ) = @_;
916 "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
918 my $record = MARC::Record->new();
919 &MARCkoha2marcOnefield( $sth, $record, "bibliosubtitle.subtitle",
924 sub MARCkoha2marcOnefield {
925 my ( $sth, $record, $kohafieldname, $value,$frameworkcode ) = @_;
928 $sth->execute($frameworkcode,$kohafieldname);
929 if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) {
930 if ( $record->field($tagfield) ) {
931 my $tag = $record->field($tagfield);
933 $tag->add_subfields( $tagsubfield, $value );
934 $record->delete_field($tag);
935 $record->add_fields($tag);
939 $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value );
946 my ($dbh,$rtags,$rsubfields,$rvalues,%indicators) = @_;
948 my $record = MARC::Record->new();
949 # my %subfieldlist=();
950 my $prevvalue; # if tag <10
951 my $field; # if tag >=10
952 for (my $i=0; $i< @$rtags; $i++) {
953 next unless @$rvalues[$i];
954 # rebuild MARC::Record
955 # warn "0=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ";
956 if (@$rtags[$i] ne $prevtag) {
959 if ($prevtag ne '000') {
960 $record->add_fields((sprintf "%03s",$prevtag),$prevvalue);
962 $record->leader($prevvalue);
967 $record->add_fields($field);
970 $indicators{@$rtags[$i]}.=' ';
971 if (@$rtags[$i] <10) {
972 $prevvalue= @$rvalues[$i];
976 $field = MARC::Field->new( (sprintf "%03s",@$rtags[$i]), substr($indicators{@$rtags[$i]},0,1),substr($indicators{@$rtags[$i]},1,1), @$rsubfields[$i] => @$rvalues[$i]);
977 # warn "1=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
979 $prevtag = @$rtags[$i];
981 if (@$rtags[$i] <10) {
982 $prevvalue=@$rvalues[$i];
984 if (length(@$rvalues[$i])>0) {
985 $field->add_subfields(@$rsubfields[$i] => @$rvalues[$i]);
986 # warn "2=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
989 $prevtag= @$rtags[$i];
992 # the last has not been included inside the loop... do it now !
993 $record->add_fields($field) if $field;
994 # warn "HTML2MARC=".$record->as_formatted;
999 my ($dbh,$record,$frameworkcode) = @_;
1000 my $sth=$dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
1002 my $sth2=$dbh->prepare("SHOW COLUMNS from biblio");
1005 while (($field)=$sth2->fetchrow) {
1006 $result=&MARCmarc2kohaOneField($sth,"biblio",$field,$record,$result,$frameworkcode);
1008 $sth2=$dbh->prepare("SHOW COLUMNS from biblioitems");
1010 while (($field)=$sth2->fetchrow) {
1011 if ($field eq 'notes') { $field = 'bnotes'; }
1012 $result=&MARCmarc2kohaOneField($sth,"biblioitems",$field,$record,$result,$frameworkcode);
1014 $sth2=$dbh->prepare("SHOW COLUMNS from items");
1016 while (($field)=$sth2->fetchrow) {
1017 $result=&MARCmarc2kohaOneField($sth,"items",$field,$record,$result,$frameworkcode);
1019 # additional authors : specific
1020 $result = &MARCmarc2kohaOneField($sth,"bibliosubtitle","subtitle",$record,$result,$frameworkcode);
1021 $result = &MARCmarc2kohaOneField($sth,"additionalauthors","additionalauthors",$record,$result,$frameworkcode);
1022 # modify copyrightdate to keep only the 1st year found
1023 my $temp = $result->{'copyrightdate'};
1024 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
1026 $result->{'copyrightdate'} = $1;
1027 } else { # if no cYYYY, get the 1st date.
1028 $temp =~ m/(\d\d\d\d)/;
1029 $result->{'copyrightdate'} = $1;
1031 # modify publicationyear to keep only the 1st year found
1032 $temp = $result->{'publicationyear'};
1033 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
1035 $result->{'publicationyear'} = $1;
1036 } else { # if no cYYYY, get the 1st date.
1037 $temp =~ m/(\d\d\d\d)/;
1038 $result->{'publicationyear'} = $1;
1043 sub MARCmarc2kohaOneField {
1045 # FIXME ? if a field has a repeatable subfield that is used in old-db, only the 1st will be retrieved...
1046 my ( $sth, $kohatable, $kohafield, $record, $result,$frameworkcode ) = @_;
1047 # warn "kohatable / $kohafield / $result / ";
1051 ( $tagfield, $subfield ) = MARCfind_marc_from_kohafield("",$kohatable.".".$kohafield,$frameworkcode);
1052 foreach my $field ( $record->field($tagfield) ) {
1053 if ($field->tag()<10) {
1054 if ($result->{$kohafield}) {
1055 $result->{$kohafield} .= " | ".$field->data();
1057 $result->{$kohafield} = $field->data();
1060 if ( $field->subfields ) {
1061 my @subfields = $field->subfields();
1062 foreach my $subfieldcount ( 0 .. $#subfields ) {
1063 if ($subfields[$subfieldcount][0] eq $subfield) {
1064 if ( $result->{$kohafield} ) {
1065 $result->{$kohafield} .= " | " . $subfields[$subfieldcount][1];
1068 $result->{$kohafield} = $subfields[$subfieldcount][1];
1075 # warn "OneField for $kohatable.$kohafield and $frameworkcode=> $tagfield, $subfield";
1081 # split a subfield string and adds it into the word table.
1084 $dbh, $bibid, $tag, $tagorder,
1085 $subfieldid, $subfieldorder, $sentence
1088 $sentence =~ s/(\.|\?|\:|\!|\'|,|\-|\"|\(|\)|\[|\]|\{|\}|\/)/ /g;
1089 my @words = split / /, $sentence;
1090 my $stopwords = C4::Context->stopwords;
1093 "insert into marc_word (bibid, tagsubfield, tagorder, subfieldorder, word, sndx_word)
1094 values (?,concat(?,?),?,?,?,soundex(?))"
1096 foreach my $word (@words) {
1097 # we record only words one char long and not in stopwords hash
1098 if (length($word)>=1 and !($stopwords->{uc($word)})) {
1099 $sth->execute($bibid,$tag,$subfieldid,$tagorder,$subfieldorder,$word,$word);
1101 warn "ERROR ==> insert into marc_word (bibid, tagsubfield, tagorder, subfieldorder, word, sndx_word) values ($bibid,concat($tag,$subfieldid),$tagorder,$subfieldorder,$word,soundex($word))\n";
1109 # delete words. this sub deletes all the words from a sentence. a subfield modif is done by a delete then a add
1110 my ( $dbh, $bibid, $tag, $tagorder, $subfield, $subfieldorder ) = @_;
1113 "delete from marc_word where bibid=? and tagsubfield=concat(?,?) and tagorder=? and subfieldorder=?"
1115 $sth->execute( $bibid, $tag, $subfield, $tagorder, $subfieldorder );
1120 # NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW
1123 # all the following subs are useful to manage MARC-DB with complete MARC records.
1124 # it's used with marcimport, and marc management tools
1127 =item ($bibid,$oldbibnum,$oldbibitemnum) = NEWnewbibilio($dbh,$MARCRecord,$frameworkcode);
1129 creates a biblio from a MARC::Record.
1131 =item NEWnewitem($dbh, $record,$bibid);
1133 creates an item from a MARC::Record
1138 my ( $dbh, $record, $frameworkcode ) = @_;
1140 my $biblioitemnumber;
1141 my $olddata = MARCmarc2koha( $dbh, $record,$frameworkcode );
1142 $olddata->{frameworkcode} = $frameworkcode;
1143 $biblionumber = OLDnewbiblio( $dbh, $olddata );
1144 $olddata->{biblionumber} = $biblionumber;
1145 # add biblionumber into the MARC record (it's the ID for zebra)
1146 my ( $tagfield, $tagsubfield ) =
1147 MARCfind_marc_from_kohafield( $dbh, "biblio.biblionumber",$frameworkcode );
1151 $newfield = MARC::Field->new(
1152 $tagfield, $biblionumber,
1155 $newfield = MARC::Field->new(
1156 $tagfield, '', '', "$tagsubfield" => $biblionumber,
1159 # drop old field (just in case it already exist and create new one...
1160 my $old_field = $record->field($tagfield);
1161 $record->delete_field($old_field);
1162 $record->add_fields($newfield);
1164 #create the marc entry, that stores the rax marc record in Koha 3.0
1165 $olddata->{marc} = $record->as_usmarc();
1166 $olddata->{marcxml} = $record->as_xml();
1167 # and create biblioitem, that's all folks !
1168 $biblioitemnumber = OLDnewbiblioitem( $dbh, $olddata );
1170 # search subtiles, addiauthors and subjects
1171 ( $tagfield, $tagsubfield ) =
1172 MARCfind_marc_from_kohafield( $dbh, "additionalauthors.author",$frameworkcode );
1173 my @addiauthfields = $record->field($tagfield);
1174 foreach my $addiauthfield (@addiauthfields) {
1175 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
1176 foreach my $subfieldcount ( 0 .. $#addiauthsubfields ) {
1177 OLDmodaddauthor( $dbh, $biblionumber,
1178 $addiauthsubfields[$subfieldcount] );
1181 ( $tagfield, $tagsubfield ) =
1182 MARCfind_marc_from_kohafield( $dbh, "bibliosubtitle.subtitle",$frameworkcode );
1183 my @subtitlefields = $record->field($tagfield);
1184 foreach my $subtitlefield (@subtitlefields) {
1185 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
1186 foreach my $subfieldcount ( 0 .. $#subtitlesubfields ) {
1187 OLDnewsubtitle( $dbh, $biblionumber,
1188 $subtitlesubfields[$subfieldcount] );
1191 ( $tagfield, $tagsubfield ) =
1192 MARCfind_marc_from_kohafield( $dbh, "bibliosubject.subject",$frameworkcode );
1193 my @subj = $record->field($tagfield);
1195 foreach my $subject (@subj) {
1196 my @subjsubfield = $subject->subfield($tagsubfield);
1197 foreach my $subfieldcount ( 0 .. $#subjsubfield ) {
1198 push @subjects, $subjsubfield[$subfieldcount];
1201 OLDmodsubject( $dbh, $biblionumber, 1, @subjects );
1202 return ( $biblionumber, $biblioitemnumber );
1205 sub NEWmodbiblioframework {
1206 my ($dbh,$bibid,$frameworkcode) =@_;
1207 my $sth = $dbh->prepare("Update marc_biblio SET frameworkcode=? WHERE bibid=$bibid");
1208 $sth->execute($frameworkcode);
1213 my ($dbh,$record,$biblionumber,$frameworkcode) =@_;
1214 $frameworkcode="" unless $frameworkcode;
1215 # &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,0);
1216 my $oldbiblio = MARCmarc2koha($dbh,$record,$frameworkcode);
1218 $oldbiblio->{frameworkcode} = $frameworkcode;
1219 #create the marc entry, that stores the rax marc record in Koha 3.0
1220 $oldbiblio->{marc} = $record->as_usmarc();
1221 $oldbiblio->{marcxml} = $record->as_xml();
1223 OLDmodbiblio($dbh,$oldbiblio);
1224 OLDmodbibitem($dbh,$oldbiblio);
1225 # now, modify addi authors, subject, addititles.
1226 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"additionalauthors.author",$frameworkcode);
1227 my @addiauthfields = $record->field($tagfield);
1228 foreach my $addiauthfield (@addiauthfields) {
1229 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
1230 foreach my $subfieldcount (0..$#addiauthsubfields) {
1231 OLDmodaddauthor($dbh,$biblionumber,$addiauthsubfields[$subfieldcount]);
1234 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubtitle.subtitle",$frameworkcode);
1235 my @subtitlefields = $record->field($tagfield);
1236 foreach my $subtitlefield (@subtitlefields) {
1237 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
1238 # delete & create subtitle again because OLDmodsubtitle can't handle new subtitles
1240 $dbh->do("delete from bibliosubtitle where biblionumber=$biblionumber");
1241 foreach my $subfieldcount (0..$#subtitlesubfields) {
1242 foreach my $subtit(split /\||#/,$subtitlesubfields[$subfieldcount]) {
1243 OLDnewsubtitle($dbh,$biblionumber,$subtit);
1247 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubject.subject",$frameworkcode);
1248 my @subj = $record->field($tagfield);
1250 foreach my $subject (@subj) {
1251 my @subjsubfield = $subject->subfield($tagsubfield);
1252 foreach my $subfieldcount (0..$#subjsubfield) {
1253 push @subjects,$subjsubfield[$subfieldcount];
1256 OLDmodsubject($dbh,$biblionumber,1,@subjects);
1261 my ( $dbh, $bibid ) = @_;
1262 my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
1263 &OLDdelbiblio( $dbh, $biblio );
1266 "select biblioitemnumber from biblioitems where biblionumber=?");
1267 $sth->execute($biblio);
1268 while ( my ($biblioitemnumber) = $sth->fetchrow ) {
1269 OLDdeletebiblioitem( $dbh, $biblioitemnumber );
1271 &MARCdelbiblio( $dbh, $bibid, 0 );
1275 my ( $dbh, $record, $bibid ) = @_;
1277 # add item in old-DB
1278 my $frameworkcode=MARCfind_frameworkcode($dbh,$bibid);
1279 my $item = &MARCmarc2koha( $dbh, $record,$frameworkcode );
1280 # needs old biblionumber and biblioitemnumber
1281 $item->{'biblionumber'} =
1282 MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
1285 "select biblioitemnumber from biblioitems where biblionumber=?");
1286 $sth->execute( $item->{'biblionumber'} );
1287 ( $item->{'biblioitemnumber'} ) = $sth->fetchrow;
1288 my ( $itemnumber, $error ) = &OLDnewitems( $dbh, $item, $item->{barcode} );
1290 # add itemnumber to MARC::Record before adding the item.
1293 "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
1295 &MARCkoha2marcOnefield( $sth, $record, "items.itemnumber", $itemnumber,$frameworkcode );
1298 my $bib = &MARCadditem( $dbh, $record, $item->{'biblionumber'} );
1302 my ( $dbh, $record, $bibid, $itemnumber, $delete ) = @_;
1304 &MARCmoditem( $dbh, $record, $bibid, $itemnumber, $delete );
1305 my $frameworkcode=MARCfind_frameworkcode($dbh,$bibid);
1306 my $olditem = MARCmarc2koha( $dbh, $record,$frameworkcode );
1307 OLDmoditem( $dbh, $olditem );
1311 my ( $dbh, $bibid, $itemnumber ) = @_;
1312 my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
1313 &OLDdelitem( $dbh, $itemnumber );
1314 &MARCdelitem( $dbh, $bibid, $itemnumber );
1319 # OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD
1323 =item $biblionumber = OLDnewbiblio($dbh,$biblio);
1325 adds a record in biblio table. Datas are in the hash $biblio.
1327 =item $biblionumber = OLDmodbiblio($dbh,$biblio);
1329 modify a record in biblio table. Datas are in the hash $biblio.
1331 =item OLDmodsubtitle($dbh,$bibnum,$subtitle);
1333 modify subtitles in bibliosubtitle table.
1335 =item OLDmodaddauthor($dbh,$bibnum,$author);
1337 adds or modify additional authors
1338 NOTE : Strange sub : seems to delete MANY and add only ONE author... maybe buggy ?
1340 =item $errors = OLDmodsubject($dbh,$bibnum, $force, @subject);
1342 modify/adds subjects
1344 =item OLDmodbibitem($dbh, $biblioitem);
1348 =item OLDmodnote($dbh,$bibitemnum,$note
1350 modify a note for a biblioitem
1352 =item OLDnewbiblioitem($dbh,$biblioitem);
1354 adds a biblioitem ($biblioitem is a hash with the values)
1356 =item OLDnewsubject($dbh,$bibnum);
1360 =item OLDnewsubtitle($dbh,$bibnum,$subtitle);
1362 create a new subtitle
1364 =item ($itemnumber,$errors)= OLDnewitems($dbh,$item,$barcode);
1366 create a item. $item is a hash and $barcode the barcode.
1368 =item OLDmoditem($dbh,$item);
1372 =item OLDdelitem($dbh,$itemnum);
1376 =item OLDdeletebiblioitem($dbh,$biblioitemnumber);
1378 deletes a biblioitem
1379 NOTE : not standard sub name. Should be OLDdelbiblioitem()
1381 =item OLDdelbiblio($dbh,$biblio);
1388 my ( $dbh, $biblio ) = @_;
1390 $dbh->do('lock tables biblio WRITE');
1391 my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
1393 my $data = $sth->fetchrow_arrayref;
1394 my $bibnum = $$data[0] + 1;
1397 if ( $biblio->{'seriestitle'} ) { $series = 1 }
1400 $dbh->prepare("insert into biblio set biblionumber=?, title=?, author=?, copyrightdate=?,
1401 serial=?, seriestitle=?, notes=?, abstract=?,
1405 $bibnum, $biblio->{'title'},
1406 $biblio->{'author'}, $biblio->{'copyrightdate'},
1407 $biblio->{'serial'}, $biblio->{'seriestitle'},
1408 $biblio->{'notes'}, $biblio->{'abstract'},
1409 $biblio->{'unititle'}
1413 $dbh->do('unlock tables');
1418 my ( $dbh, $biblio ) = @_;
1419 my $sth = $dbh->prepare("Update biblio set title=?, author=?, abstract=?, copyrightdate=?,
1420 seriestitle=?, serial=?, unititle=?, notes=?, frameworkcode=?
1421 where biblionumber = ?"
1424 $biblio->{'title'}, $biblio->{'author'},
1425 $biblio->{'abstract'}, $biblio->{'copyrightdate'},
1426 $biblio->{'seriestitle'}, $biblio->{'serial'},
1427 $biblio->{'unititle'}, $biblio->{'notes'},
1428 $biblio->{frameworkcode},
1429 $biblio->{'biblionumber'}
1432 return ( $biblio->{'biblionumber'} );
1435 sub OLDmodsubtitle {
1436 my ( $dbh, $bibnum, $subtitle ) = @_;
1439 "update bibliosubtitle set subtitle = ? where biblionumber = ?");
1440 $sth->execute( $subtitle, $bibnum );
1444 sub OLDmodaddauthor {
1445 my ( $dbh, $bibnum, @authors ) = @_;
1447 # my $dbh = C4Connect;
1449 $dbh->prepare("Delete from additionalauthors where biblionumber = ?");
1451 $sth->execute($bibnum);
1453 foreach my $author (@authors) {
1454 if ( $author ne '' ) {
1457 "Insert into additionalauthors set author = ?, biblionumber = ?"
1460 $sth->execute( $author, $bibnum );
1465 } # sub modaddauthor
1468 my ( $dbh, $bibnum, $force, @subject ) = @_;
1470 # my $dbh = C4Connect;
1471 my $count = @subject;
1473 for ( my $i = 0 ; $i < $count ; $i++ ) {
1474 $subject[$i] =~ s/^ //g;
1475 $subject[$i] =~ s/ $//g;
1478 "select * from catalogueentry where entrytype = 's' and catalogueentry = ?"
1480 $sth->execute( $subject[$i] );
1482 if ( my $data = $sth->fetchrow_hashref ) {
1485 if ( $force eq $subject[$i] || $force == 1 ) {
1487 # subject not in aut, chosen to force anway
1488 # so insert into cataloguentry so its in auth file
1491 "Insert into catalogueentry (entrytype,catalogueentry) values ('s',?)"
1494 $sth2->execute( $subject[$i] ) if ( $subject[$i] );
1499 "$subject[$i]\n does not exist in the subject authority file";
1502 "Select * from catalogueentry where entrytype = 's' and (catalogueentry like ? or catalogueentry like ? or catalogueentry like ?)"
1504 $sth2->execute( "$subject[$i] %", "% $subject[$i] %",
1506 while ( my $data = $sth2->fetchrow_hashref ) {
1507 $error .= "<br>$data->{'catalogueentry'}";
1514 if ( $error eq '' ) {
1516 $dbh->prepare("Delete from bibliosubject where biblionumber = ?");
1517 $sth->execute($bibnum);
1521 "Insert into bibliosubject (subject,biblionumber) values (?,?)");
1523 foreach $query (@subject) {
1524 $sth->execute( $query, $bibnum ) if ( $query && $bibnum );
1534 my ( $dbh, $biblioitem ) = @_;
1537 my $sth = $dbh->prepare("update biblioitems set itemtype=?, url=?, isbn=?, issn=?,
1538 publishercode=?, publicationyear=?, classification=?, dewey=?,
1539 subclass=?, illus=?, pages=?, volumeddesc=?,
1540 notes=?, size=?, place=?, marc=?,
1542 where biblioitemnumber=?");
1543 $sth->execute( $biblioitem->{itemtype}, $biblioitem->{url}, $biblioitem->{isbn}, $biblioitem->{issn},
1544 $biblioitem->{publishercode}, $biblioitem->{publicationyear}, $biblioitem->{classification}, $biblioitem->{dewey},
1545 $biblioitem->{subclass}, $biblioitem->{illus}, $biblioitem->{pages}, $biblioitem->{volumeddesc},
1546 $biblioitem->{bnotes}, $biblioitem->{size}, $biblioitem->{place}, $biblioitem->{marc},
1547 $biblioitem->{marcxml}, $biblioitem->{biblioitemnumber});
1548 # warn "MOD : $biblioitem->{biblioitemnumber} = ".$biblioitem->{marc};
1552 my ( $dbh, $bibitemnum, $note ) = @_;
1554 # my $dbh=C4Connect;
1555 my $query = "update biblioitems set notes='$note' where
1556 biblioitemnumber='$bibitemnum'";
1557 my $sth = $dbh->prepare($query);
1564 sub OLDnewbiblioitem {
1565 my ( $dbh, $biblioitem ) = @_;
1567 # my $dbh = C4Connect;
1568 my $sth = $dbh->prepare("Select max(biblioitemnumber) from biblioitems");
1573 $data = $sth->fetchrow_arrayref;
1574 $bibitemnum = $$data[0] + 1;
1578 $sth = $dbh->prepare( "insert into biblioitems set
1579 biblioitemnumber = ?, biblionumber = ?,
1580 volume = ?, number = ?,
1581 classification = ?, itemtype = ?,
1583 issn = ?, dewey = ?,
1584 subclass = ?, publicationyear = ?,
1585 publishercode = ?, volumedate = ?,
1586 volumeddesc = ?, illus = ?,
1587 pages = ?, notes = ?,
1589 marc = ?, place = ?,
1593 $bibitemnum, $biblioitem->{'biblionumber'},
1594 $biblioitem->{'volume'}, $biblioitem->{'number'},
1595 $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
1596 $biblioitem->{'url'}, $biblioitem->{'isbn'},
1597 $biblioitem->{'issn'}, $biblioitem->{'dewey'},
1598 $biblioitem->{'subclass'}, $biblioitem->{'publicationyear'},
1599 $biblioitem->{'publishercode'}, $biblioitem->{'volumedate'},
1600 $biblioitem->{'volumeddesc'}, $biblioitem->{'illus'},
1601 $biblioitem->{'pages'}, $biblioitem->{'bnotes'},
1602 $biblioitem->{'size'}, $biblioitem->{'lccn'},
1603 $biblioitem->{'marc'}, $biblioitem->{'place'},
1604 $biblioitem->{marcxml},
1609 return ($bibitemnum);
1613 my ( $dbh, $bibnum ) = @_;
1615 $dbh->prepare("insert into bibliosubject (biblionumber) values (?)");
1616 $sth->execute($bibnum);
1620 sub OLDnewsubtitle {
1621 my ( $dbh, $bibnum, $subtitle ) = @_;
1624 "insert into bibliosubtitle set biblionumber = ?, subtitle = ?");
1625 $sth->execute( $bibnum, $subtitle ) if $subtitle;
1630 my ( $dbh, $item, $barcode ) = @_;
1632 # my $dbh = C4Connect;
1633 my $sth = $dbh->prepare("Select max(itemnumber) from items");
1639 $data = $sth->fetchrow_hashref;
1640 $itemnumber = $data->{'max(itemnumber)'} + 1;
1643 # FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
1644 if ( $item->{'loan'} ) {
1645 $item->{'notforloan'} = $item->{'loan'};
1648 # if dateaccessioned is provided, use it. Otherwise, set to NOW()
1649 if ( $item->{'dateaccessioned'} ) {
1650 $sth = $dbh->prepare( "Insert into items set
1651 itemnumber = ?, biblionumber = ?,
1652 multivolumepart = ?,
1653 biblioitemnumber = ?, barcode = ?,
1654 booksellerid = ?, dateaccessioned = ?,
1655 homebranch = ?, holdingbranch = ?,
1656 price = ?, replacementprice = ?,
1657 replacementpricedate = NOW(), datelastseen = NOW(),
1658 multivolume = ?, stack = ?,
1659 itemlost = ?, wthdrawn = ?,
1660 paidfor = ?, itemnotes = ?,
1661 itemcallnumber =?, notforloan = ?,
1666 $itemnumber, $item->{'biblionumber'},
1667 $item->{'multivolumepart'},
1668 $item->{'biblioitemnumber'},$barcode,
1669 $item->{'booksellerid'}, $item->{'dateaccessioned'},
1670 $item->{'homebranch'}, $item->{'holdingbranch'},
1671 $item->{'price'}, $item->{'replacementprice'},
1672 $item->{multivolume}, $item->{stack},
1673 $item->{itemlost}, $item->{wthdrawn},
1674 $item->{paidfor}, $item->{'itemnotes'},
1675 $item->{'itemcallnumber'}, $item->{'notforloan'},
1680 $sth = $dbh->prepare( "Insert into items set
1681 itemnumber = ?, biblionumber = ?,
1682 multivolumepart = ?,
1683 biblioitemnumber = ?, barcode = ?,
1684 booksellerid = ?, dateaccessioned = NOW(),
1685 homebranch = ?, holdingbranch = ?,
1686 price = ?, replacementprice = ?,
1687 replacementpricedate = NOW(), datelastseen = NOW(),
1688 multivolume = ?, stack = ?,
1689 itemlost = ?, wthdrawn = ?,
1690 paidfor = ?, itemnotes = ?,
1691 itemcallnumber =?, notforloan = ?,
1696 $itemnumber, $item->{'biblionumber'},
1697 $item->{'multivolumepart'},
1698 $item->{'biblioitemnumber'},$barcode,
1699 $item->{'booksellerid'},
1700 $item->{'homebranch'}, $item->{'holdingbranch'},
1701 $item->{'price'}, $item->{'replacementprice'},
1702 $item->{multivolume}, $item->{stack},
1703 $item->{itemlost}, $item->{wthdrawn},
1704 $item->{paidfor}, $item->{'itemnotes'},
1705 $item->{'itemcallnumber'}, $item->{'notforloan'},
1709 if ( defined $sth->errstr ) {
1710 $error .= $sth->errstr;
1713 return ( $itemnumber, $error );
1717 my ( $dbh, $item ) = @_;
1718 $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
1719 my $query = "update items set barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1721 $item->{'barcode'}, $item->{'notes'},
1722 $item->{'itemcallnumber'}, $item->{'notforloan'},
1723 $item->{'location'}, $item->{multivolumepart},
1724 $item->{multivolume}, $item->{stack},
1727 if ( $item->{'lost'} ne '' ) {
1728 $query = "update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
1729 itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
1730 location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1732 $item->{'bibitemnum'}, $item->{'barcode'},
1733 $item->{'notes'}, $item->{'homebranch'},
1734 $item->{'lost'}, $item->{'wthdrawn'},
1735 $item->{'itemcallnumber'}, $item->{'notforloan'},
1736 $item->{'location'}, $item->{multivolumepart},
1737 $item->{multivolume}, $item->{stack},
1740 if ($item->{homebranch}) {
1741 $query.=",homebranch=?";
1742 push @bind, $item->{homebranch};
1744 if ($item->{holdingbranch}) {
1745 $query.=",holdingbranch=?";
1746 push @bind, $item->{holdingbranch};
1749 $query.=" where itemnumber=?";
1750 push @bind,$item->{'itemnum'};
1751 if ( $item->{'replacement'} ne '' ) {
1752 $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
1754 my $sth = $dbh->prepare($query);
1755 $sth->execute(@bind);
1762 my ( $dbh, $itemnum ) = @_;
1764 # my $dbh=C4Connect;
1765 my $sth = $dbh->prepare("select * from items where itemnumber=?");
1766 $sth->execute($itemnum);
1767 my $data = $sth->fetchrow_hashref;
1769 my $query = "Insert into deleteditems set ";
1771 foreach my $temp ( keys %$data ) {
1772 $query .= "$temp = ?,";
1773 push ( @bind, $data->{$temp} );
1778 $sth = $dbh->prepare($query);
1779 $sth->execute(@bind);
1781 $sth = $dbh->prepare("Delete from items where itemnumber=?");
1782 $sth->execute($itemnum);
1788 sub OLDdeletebiblioitem {
1789 my ( $dbh, $biblioitemnumber ) = @_;
1791 # my $dbh = C4Connect;
1792 my $sth = $dbh->prepare( "Select * from biblioitems
1793 where biblioitemnumber = ?"
1797 $sth->execute($biblioitemnumber);
1799 if ( $results = $sth->fetchrow_hashref ) {
1803 "Insert into deletedbiblioitems (biblioitemnumber, biblionumber, volume, number, classification, itemtype,
1804 isbn, issn ,dewey ,subclass ,publicationyear ,publishercode ,volumedate ,volumeddesc ,timestamp ,illus ,
1805 pages ,notes ,size ,url ,lccn ) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
1809 $results->{biblioitemnumber}, $results->{biblionumber},
1810 $results->{volume}, $results->{number},
1811 $results->{classification}, $results->{itemtype},
1812 $results->{isbn}, $results->{issn},
1813 $results->{dewey}, $results->{subclass},
1814 $results->{publicationyear}, $results->{publishercode},
1815 $results->{volumedate}, $results->{volumeddesc},
1816 $results->{timestamp}, $results->{illus},
1817 $results->{pages}, $results->{notes},
1818 $results->{size}, $results->{url},
1822 $dbh->prepare("Delete from biblioitems where biblioitemnumber = ?");
1823 $sth2->execute($biblioitemnumber);
1828 # Now delete all the items attached to the biblioitem
1829 $sth = $dbh->prepare("Select * from items where biblioitemnumber = ?");
1830 $sth->execute($biblioitemnumber);
1832 while ( my $data = $sth->fetchrow_hashref ) {
1833 my $query = "Insert into deleteditems set ";
1835 foreach my $temp ( keys %$data ) {
1836 $query .= "$temp = ?,";
1837 push ( @bind, $data->{$temp} );
1840 my $sth2 = $dbh->prepare($query);
1841 $sth2->execute(@bind);
1844 $sth = $dbh->prepare("Delete from items where biblioitemnumber = ?");
1845 $sth->execute($biblioitemnumber);
1849 } # sub deletebiblioitem
1852 my ( $dbh, $biblio ) = @_;
1853 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
1854 $sth->execute($biblio);
1855 if ( my $data = $sth->fetchrow_hashref ) {
1857 my $query = "Insert into deletedbiblio set ";
1859 foreach my $temp ( keys %$data ) {
1860 $query .= "$temp = ?,";
1861 push ( @bind, $data->{$temp} );
1864 #replacing the last , by ",?)"
1866 $sth = $dbh->prepare($query);
1867 $sth->execute(@bind);
1869 $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
1870 $sth->execute($biblio);
1884 my $dbh = C4::Context->dbh;
1887 my $sth = $dbh->prepare("Select count(*) from items where biblionumber=?");
1888 $sth->execute($biblio);
1889 my $data = $sth->fetchrow_hashref;
1891 return ( $data->{'count(*)'} );
1896 my $dbh = C4::Context->dbh;
1897 my $bibnum = OLDnewbiblio( $dbh, $biblio );
1898 # finds new (MARC bibid
1899 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1900 my $record = &MARCkoha2marcBiblio( $dbh, $bibnum );
1901 MARCaddbiblio( $dbh, $record, $bibnum,'' );
1907 $biblionumber = &modbiblio($biblio);
1909 Update a biblio record.
1911 C<$biblio> is a reference-to-hash whose keys are the fields in the
1912 biblio table in the Koha database. All fields must be present, not
1913 just the ones you wish to change.
1915 C<&modbiblio> updates the record defined by
1916 C<$biblio-E<gt>{biblionumber}> with the values in C<$biblio>.
1918 C<&modbiblio> returns C<$biblio-E<gt>{biblionumber}> whether it was
1925 my $dbh = C4::Context->dbh;
1926 my $biblionumber=OLDmodbiblio($dbh,$biblio);
1927 my $record = MARCkoha2marcBiblio($dbh,$biblionumber,$biblionumber);
1928 # finds new (MARC bibid
1929 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
1930 MARCmodbiblio($dbh,$bibid,$record,"",0);
1931 return($biblionumber);
1936 &modsubtitle($biblionumber, $subtitle);
1938 Sets the subtitle of a book.
1940 C<$biblionumber> is the biblionumber of the book to modify.
1942 C<$subtitle> is the new subtitle.
1947 my ( $bibnum, $subtitle ) = @_;
1948 my $dbh = C4::Context->dbh;
1949 &OLDmodsubtitle( $dbh, $bibnum, $subtitle );
1954 &modaddauthor($biblionumber, $author);
1956 Replaces all additional authors for the book with biblio number
1957 C<$biblionumber> with C<$author>. If C<$author> is the empty string,
1958 C<&modaddauthor> deletes all additional authors.
1963 my ( $bibnum, @authors ) = @_;
1964 my $dbh = C4::Context->dbh;
1965 &OLDmodaddauthor( $dbh, $bibnum, @authors );
1966 } # sub modaddauthor
1970 $error = &modsubject($biblionumber, $force, @subjects);
1972 $force - a subject to force
1974 $error - Error message, or undef if successful.
1979 my ( $bibnum, $force, @subject ) = @_;
1980 my $dbh = C4::Context->dbh;
1981 my $error = &OLDmodsubject( $dbh, $bibnum, $force, @subject );
1983 # When MARC is off, ensures that the MARC biblio table gets updated with new
1984 # subjects, of course, it deletes the biblio in marc, and then recreates.
1985 # This check is to ensure that no MARC data exists to lose.
1986 if (C4::Context->preference("MARC") eq '0'){
1987 my $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibnum);
1988 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1989 &MARCmodbiblio($dbh,$bibid, $MARCRecord);
1996 my ($biblioitem) = @_;
1997 my $dbh = C4::Context->dbh;
1998 &OLDmodbibitem( $dbh, $biblioitem );
2002 my ( $bibitemnum, $note ) = @_;
2003 my $dbh = C4::Context->dbh;
2004 &OLDmodnote( $dbh, $bibitemnum, $note );
2008 my ($biblioitem) = @_;
2009 my $dbh = C4::Context->dbh;
2010 my $bibitemnum = &OLDnewbiblioitem( $dbh, $biblioitem );
2013 MARCkoha2marcBiblio( $dbh, 0, $bibitemnum )
2014 ; # the 0 means "do NOT retrieve biblio, only biblioitem, in the MARC record
2016 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh,
2017 $biblioitem->{biblionumber} );
2018 &MARCaddbiblio( $dbh, $MARCbiblio, $biblioitem->{biblionumber}, '',$bibid );
2019 return ($bibitemnum);
2024 my $dbh = C4::Context->dbh;
2025 &OLDnewsubject( $dbh, $bibnum );
2029 my ( $bibnum, $subtitle ) = @_;
2030 my $dbh = C4::Context->dbh;
2031 &OLDnewsubtitle( $dbh, $bibnum, $subtitle );
2035 my ( $item, @barcodes ) = @_;
2036 my $dbh = C4::Context->dbh;
2040 foreach my $barcode (@barcodes) {
2041 ( $itemnumber, $error ) = &OLDnewitems( $dbh, $item, uc($barcode) );
2044 &MARCkoha2marcItem( $dbh, $item->{biblionumber}, $itemnumber );
2045 &MARCadditem( $dbh, $MARCitem, $item->{biblionumber} );
2052 my $dbh = C4::Context->dbh;
2053 &OLDmoditem( $dbh, $item );
2055 &MARCkoha2marcItem( $dbh, $item->{'biblionumber'}, $item->{'itemnum'} );
2057 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $item->{biblionumber} );
2058 &MARCmoditem( $dbh, $MARCitem, $bibid, $item->{itemnum}, 0 );
2062 my ( $count, @barcodes ) = @_;
2063 my $dbh = C4::Context->dbh;
2065 my $sth = $dbh->prepare("Select * from items where barcode=?");
2066 for ( my $i = 0 ; $i < $count ; $i++ ) {
2067 $barcodes[$i] = uc $barcodes[$i];
2068 $sth->execute( $barcodes[$i] );
2069 if ( my $data = $sth->fetchrow_hashref ) {
2070 $error .= " Duplicate Barcode: $barcodes[$i]";
2078 my ($bibitemnum) = @_;
2079 my $dbh = C4::Context->dbh;
2082 $dbh->prepare("Select count(*) from items where biblioitemnumber=?");
2083 $sth->execute($bibitemnum);
2084 my $data = $sth->fetchrow_hashref;
2086 return ( $data->{'count(*)'} );
2091 my $dbh = C4::Context->dbh;
2092 &OLDdelitem( $dbh, $itemnum );
2095 sub deletebiblioitem {
2096 my ($biblioitemnumber) = @_;
2097 my $dbh = C4::Context->dbh;
2098 &OLDdeletebiblioitem( $dbh, $biblioitemnumber );
2099 } # sub deletebiblioitem
2103 my $dbh = C4::Context->dbh;
2104 &OLDdelbiblio( $dbh, $biblio );
2105 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $biblio );
2106 &MARCdelbiblio( $dbh, $bibid, 0 );
2110 my ($biblionumber) = @_;
2111 my $dbh = C4::Context->dbh;
2112 my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
2114 # || die "Cannot prepare $query\n" . $dbh->errstr;
2118 $sth->execute($biblionumber);
2120 # || die "Cannot execute $query\n" . $sth->errstr;
2121 while ( my $data = $sth->fetchrow_hashref ) {
2122 $results[$count] = $data;
2127 return ( $count, @results );
2131 my ($biblioitemnum) = @_;
2132 my $dbh = C4::Context->dbh;
2133 my $sth = $dbh->prepare( "Select * from biblioitems where
2134 biblioitemnumber = ?"
2139 $sth->execute($biblioitemnum);
2141 while ( my $data = $sth->fetchrow_hashref ) {
2142 $results[$count] = $data;
2147 return ( $count, @results );
2148 } # sub getbiblioitem
2150 sub getbiblioitembybiblionumber {
2151 my ($biblionumber) = @_;
2152 my $dbh = C4::Context->dbh;
2153 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
2157 $sth->execute($biblionumber);
2159 while ( my $data = $sth->fetchrow_hashref ) {
2160 $results[$count] = $data;
2165 return ( $count, @results );
2169 my $dbh = C4::Context->dbh;
2170 my $query = "select * from itemtypes order by description";
2171 my $sth = $dbh->prepare($query);
2173 # || die "Cannot prepare $query" . $dbh->errstr;
2179 # || die "Cannot execute $query\n" . $sth->errstr;
2180 while ( my $data = $sth->fetchrow_hashref ) {
2181 $results[$count] = $data;
2186 return ( $count, @results );
2187 } # sub getitemtypes
2189 sub getitemsbybiblioitem {
2190 my ($biblioitemnum) = @_;
2191 my $dbh = C4::Context->dbh;
2192 my $sth = $dbh->prepare( "Select * from items, biblio where
2193 biblio.biblionumber = items.biblionumber and biblioitemnumber
2197 # || die "Cannot prepare $query\n" . $dbh->errstr;
2201 $sth->execute($biblioitemnum);
2203 # || die "Cannot execute $query\n" . $sth->errstr;
2204 while ( my $data = $sth->fetchrow_hashref ) {
2205 $results[$count] = $data;
2210 return ( $count, @results );
2211 } # sub getitemsbybiblioitem
2215 # Subroutine to log changes to databases
2216 # Eventually, this subroutine will be used to create a log of all changes made,
2217 # with the possibility of "undo"ing some changes
2218 my $database = shift;
2219 if ( $database eq 'kohadb' ) {
2221 my $section = shift;
2223 my $original = shift;
2226 # print STDERR "KOHA: $type $section $item $original $new\n";
2228 elsif ( $database eq 'marc' ) {
2230 my $Record_ID = shift;
2233 my $subfield_ID = shift;
2234 my $original = shift;
2237 # print STDERR "MARC: $type $Record_ID $tag $mark $subfield_ID $original $new\n";
2241 #------------------------------------------------
2243 #---------------------------------------
2244 # Find a biblio entry, or create a new one if it doesn't exist.
2245 # If a "subtitle" entry is in hash, add it to subtitle table
2246 sub getoraddbiblio {
2251 # FIXME - Unused argument
2252 $biblio, # hash ref to fields
2263 $dbh = C4::Context->dbh;
2265 print "<PRE>Looking for biblio </PRE>\n" if $debug;
2266 $sth = $dbh->prepare( "select biblionumber
2268 where title=? and author=?
2269 and copyrightdate=? and seriestitle=?"
2272 $biblio->{title}, $biblio->{author},
2273 $biblio->{copyright}, $biblio->{seriestitle}
2276 ($biblionumber) = $sth->fetchrow;
2277 print "<PRE>Biblio exists with number $biblionumber</PRE>\n" if $debug;
2281 # Doesn't exist. Add new one.
2282 print "<PRE>Adding biblio</PRE>\n" if $debug;
2283 ( $biblionumber, $error ) = &newbiblio($biblio);
2284 if ($biblionumber) {
2285 print "<PRE>Added with biblio number=$biblionumber</PRE>\n"
2287 if ( $biblio->{subtitle} ) {
2288 &newsubtitle( $biblionumber, $biblio->{subtitle} );
2292 print "<PRE>Couldn't add biblio: $error</PRE>\n" if $debug;
2296 return $biblionumber, $error;
2298 } # sub getoraddbiblio
2302 # converts ISO 5426 coded string to ISO 8859-1
2303 # sloppy code : should be improved in next issue
2304 my ( $string, $encoding ) = @_;
2307 # $encoding = C4::Context->preference("marcflavour") unless $encoding;
2308 if ( $encoding eq "UNIMARC" ) {
2377 # this handles non-sorting blocks (if implementation requires this)
2378 $string = nsb_clean($_);
2380 elsif ( $encoding eq "USMARC" || $encoding eq "MARC21" ) {
2381 if (/[\xc1-\xff]/) {
2434 # this handles non-sorting blocks (if implementation requires this)
2435 $string = nsb_clean($_);
2442 my $NSB = '\x88'; # NSB : begin Non Sorting Block
2443 my $NSE = '\x89'; # NSE : Non Sorting Block end
2444 # handles non sorting blocks
2448 s/[ ]{0,1}$NSE/) /gm;
2455 my $dbh = C4::Context->dbh;
2456 my $result = MARCmarc2koha($dbh,$record,'');
2458 my ($biblionumber,$bibid,$title);
2459 # search duplicate on ISBN, easy and fast...
2460 if ($result->{isbn}) {
2461 $sth = $dbh->prepare("select biblio.biblionumber,bibid,title from biblio,biblioitems,marc_biblio where biblio.biblionumber=biblioitems.biblionumber and marc_biblio.biblionumber=biblioitems.biblionumber and isbn=?");
2462 $sth->execute($result->{'isbn'});
2463 ($biblionumber,$bibid,$title) = $sth->fetchrow;
2464 return $biblionumber,$bibid,$title if ($biblionumber);
2466 # a more complex search : build a request for SearchMarc::catalogsearch()
2467 my (@tags, @and_or, @excluding, @operator, @value, $offset,$length);
2468 # search on biblio.title
2469 my ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.title","");
2470 if ($record->field($tag)) {
2471 if ($record->field($tag)->subfields($subfield)) {
2472 push @tags, "'".$tag.$subfield."'";
2473 push @and_or, "and";
2474 push @excluding, "";
2475 push @operator, "contains";
2476 push @value, $record->field($tag)->subfield($subfield);
2477 # warn "for title, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2480 # ... and on biblio.author
2481 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.author","");
2482 if ($record->field($tag)) {
2483 if ($record->field($tag)->subfields($subfield)) {
2484 push @tags, "'".$tag.$subfield."'";
2485 push @and_or, "and";
2486 push @excluding, "";
2487 push @operator, "contains";
2488 push @value, $record->field($tag)->subfield($subfield);
2489 # warn "for author, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2492 # ... and on publicationyear.
2493 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publicationyear","");
2494 if ($record->field($tag)) {
2495 if ($record->field($tag)->subfields($subfield)) {
2496 push @tags, "'".$tag.$subfield."'";
2497 push @and_or, "and";
2498 push @excluding, "";
2499 push @operator, "=";
2500 push @value, $record->field($tag)->subfield($subfield);
2501 # warn "for publicationyear, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2505 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.size","");
2506 if ($record->field($tag)) {
2507 if ($record->field($tag)->subfields($subfield)) {
2508 push @tags, "'".$tag.$subfield."'";
2509 push @and_or, "and";
2510 push @excluding, "";
2511 push @operator, "=";
2512 push @value, $record->field($tag)->subfield($subfield);
2513 # warn "for size, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2516 # ... and on publisher.
2517 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publishercode","");
2518 if ($record->field($tag)) {
2519 if ($record->field($tag)->subfields($subfield)) {
2520 push @tags, "'".$tag.$subfield."'";
2521 push @and_or, "and";
2522 push @excluding, "";
2523 push @operator, "=";
2524 push @value, $record->field($tag)->subfield($subfield);
2525 # warn "for publishercode, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2528 # ... and on volume.
2529 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.volume","");
2530 if ($record->field($tag)) {
2531 if ($record->field($tag)->subfields($subfield)) {
2532 push @tags, "'".$tag.$subfield."'";
2533 push @and_or, "and";
2534 push @excluding, "";
2535 push @operator, "=";
2536 push @value, $record->field($tag)->subfield($subfield);
2537 # warn "for volume, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2541 my ($finalresult,$nbresult) = C4::SearchMarc::catalogsearch($dbh,\@tags,\@and_or,\@excluding,\@operator,\@value,0,10);
2542 # there is at least 1 result => return the 1st one
2544 # warn "$nbresult => ".@$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2545 return @$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2547 # no result, returns nothing
2554 if(substr($isbn, 0, 1) <=7) {
2555 $seg1 = substr($isbn, 0, 1);
2556 } elsif(substr($isbn, 0, 2) <= 94) {
2557 $seg1 = substr($isbn, 0, 2);
2558 } elsif(substr($isbn, 0, 3) <= 995) {
2559 $seg1 = substr($isbn, 0, 3);
2560 } elsif(substr($isbn, 0, 4) <= 9989) {
2561 $seg1 = substr($isbn, 0, 4);
2563 $seg1 = substr($isbn, 0, 5);
2565 my $x = substr($isbn, length($seg1));
2567 if(substr($x, 0, 2) <= 19) {
2568 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
2569 $seg2 = substr($x, 0, 2);
2570 } elsif(substr($x, 0, 3) <= 699) {
2571 $seg2 = substr($x, 0, 3);
2572 } elsif(substr($x, 0, 4) <= 8399) {
2573 $seg2 = substr($x, 0, 4);
2574 } elsif(substr($x, 0, 5) <= 89999) {
2575 $seg2 = substr($x, 0, 5);
2576 } elsif(substr($x, 0, 6) <= 9499999) {
2577 $seg2 = substr($x, 0, 6);
2579 $seg2 = substr($x, 0, 7);
2581 my $seg3=substr($x,length($seg2));
2582 $seg3=substr($seg3,0,length($seg3)-1) ;
2583 my $seg4 = substr($x, -1, 1);
2584 return "$seg1-$seg2-$seg3-$seg4";
2588 END { } # module clean-up code here (global destructor)
2594 Koha Developement team <info@koha.org>
2596 Paul POULAIN paul.poulain@free.fr
2602 # Revision 1.124 2005/08/10 10:21:15 tipaul
2603 # continuing the road to zebra :
2604 # - the biblio add begins to work.
2605 # - the biblio modif begins to work.
2607 # (still without doing anything on zebra)
2608 # (no new change in updatedatabase)
2610 # Revision 1.123 2005/08/09 14:10:28 tipaul
2611 # 1st commit to go to zebra.
2612 # don't update your cvs if you want to have a working head...
2614 # this commit contains :
2615 # * updater/updatedatabase : get rid with marc_* tables, but DON'T remove them. As a lot of things uses them, it would not be a good idea for instance to drop them. If you really want to play, you can rename them to test head without them but being still able to reintroduce them...
2616 # * Biblio.pm : modify MARCgetbiblio to find the raw marc record in biblioitems.marc field, not from marc_subfield_table, modify MARCfindframeworkcode to find frameworkcode in biblio.frameworkcode, modify some other subs to use biblio.biblionumber & get rid of bibid.
2617 # * other files : get rid of bibid and use biblionumber instead.
2620 # * does not do anything on zebra yet.
2621 # * if you rename marc_subfield_table, you can't search anymore.
2622 # * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
2623 # * don't try to add a biblio, it would add data poorly... (don't try to delete either, it may work, but that would be a surprise ;-) )
2625 # IMPORTANT NOTE : you need MARC::XML package (http://search.cpan.org/~esummers/MARC-XML-0.7/lib/MARC/File/XML.pm), that requires a recent version of MARC::Record
2626 # Updatedatabase stores the iso2709 data in biblioitems.marc field & an xml version in biblioitems.marcxml Not sure we will keep it when releasing the stable version, but I think it's a good idea to have something readable in sql, at least for development stage.
2628 # Revision 1.122 2005/08/04 13:27:48 tipaul
2629 # synch'ing 2.2 and head
2631 # Revision 1.115.2.18 2005/08/02 07:45:44 tipaul
2632 # fix for bug http://bugs.koha.org/cgi-bin/bugzilla/show_bug.cgi?id=1009
2633 # (Not all items fields mapped to MARC)
2635 # Revision 1.115.2.17 2005/08/01 15:15:43 tipaul
2636 # adding decoder for Ä string
2638 # Revision 1.115.2.16 2005/07/28 19:56:15 tipaul
2639 # * removing a useless & CPU consuming call to MARCgetbiblio
2640 # * Leader management.
2641 # If you create a MARC tag "000", with a subfield '@', it will be managed as the leader.
2642 # Seems to work correctly.
2644 # Now going to create a plugin for leader()
2646 # Revision 1.115.2.15 2005/07/19 15:25:40 tipaul
2647 # * fixing a bug in subfield order when MARCgetbiblio
2648 # * getting rid with the limit "biblionumber & biblioitemnumber must be in the same tag". So, we can put biblionumber in 001 (field that has no subfields, so we can't put biblioitemnumber in this field), and use biblionumber as identifier in the MARC biblio too. Still to be deeply tested.
2649 # * adding some diacritic decoding (Ä, Ü...)
2651 # Revision 1.115.2.14 2005/06/27 23:24:06 hdl
2652 # Display dashed ISBN
2654 # Revision 1.115.2.13 2005/05/31 12:44:26 tipaul
2655 # patch from Genji (Waylon R.) to update subjects in MARC tables when systempref has MARC=OFF
2657 # Revision 1.115.2.12 2005/05/30 11:22:41 tipaul
2658 # fixing a bug : when a field was repeated, the last field was also repeated. (Was due to the "empty" field in html between fields : to separate fields, in html, an empty field is automatically added. in MARChtml2marc, this empty field was not discarded correctly)
2660 # Revision 1.115.2.11 2005/05/25 15:48:43 tipaul
2661 # * removing my for variables already declared
2662 # * updating biblio.unititle field as well as other fields in biblio table
2664 # Revision 1.115.2.10 2005/05/25 09:30:50 hdl
2665 # Adding NEWmodbiblioframework feature
2666 # Used by addbiblio.pl when modifying a framework selection.
2668 # Revision 1.115.2.9 2005/04/07 10:05:25 tipaul
2669 # adding / to the list of symbols that are replace by spaces for searches
2671 # Revision 1.115.2.8 2005/03/25 16:23:49 tipaul
2672 # some improvements :
2673 # * return immediatly when a subfield is empty
2674 # * search duplicate on isbn must be done only when there is an isbn ;-)
2676 # Revision 1.115.2.7 2005/03/10 15:52:28 tipaul
2677 # * adding glass to opac marc detail.
2678 # * changing glasses behaviour : It now appears only on subfields that have a "link" value. Avoid useless glasses and removes nothing. **** WARNING **** : if you don't change you MARC parameters, glasses DISAPPEAR, because no subfields have a link value. So you MUST "reactivate" them manually. If you want to enable the search glass on field 225$a (collection in UNIMARC), just put 225a to "link" field (Koha >> parameters >> framework >> 225 field >> subfield >> modify $a >> enter 225a in link input field (without quotes or anything else)
2679 # * fixing bug with libopac
2681 # Revision 1.115.2.6 2005/03/09 15:56:01 tipaul
2682 # Changing MARCmoditem to be like MARCmodbiblio : a modif is a delete & create.
2683 # Longer, but solves problems with repeated subfields.
2685 # The previous version was not buggy except under certain circumstances (a repeated subfield, that does not exist usually in items)
2687 # Revision 1.115.2.5 2005/02/24 13:54:04 tipaul
2688 # exporting MARCdelsubfield sub. It's used in authority merging.
2689 # Modifying it too to enable deletion of all subfields from a given tag/subfield or just one.
2691 # Revision 1.115.2.4 2005/02/17 12:44:25 tipaul
2692 # bug in acquisition : the title was also stored as subtitle.
2694 # Revision 1.115.2.3 2005/02/10 13:14:36 tipaul
2695 # * multiple main authors are now correctly handled in simple (non-MARC) view
2697 # Revision 1.115.2.2 2005/01/11 16:02:35 tipaul
2698 # in catalogue, modifs were not stored properly the non-MARC item DB. Affect only libraries without barcodes.
2700 # Revision 1.115.2.1 2005/01/11 14:45:37 tipaul
2701 # bugfix : issn were not stored correctly in non-MARC DB on biblio modification
2703 # Revision 1.115 2005/01/06 14:32:17 tipaul
2704 # improvement of speed for bulkmarcimport.
2705 # A sub had been forgotten to use the C4::Context->marcfromkohafield array, that caches DB datas.
2706 # this is only a little improvement for normal DB modif, but almost x2 the speed of bulkmarcimport... from 6records/seconds to more than 10.
2708 # Revision 1.114 2005/01/03 10:48:33 tipaul
2709 # * bugfix for the search on a MARC detail, when you clic on the magnifying glass (caused an internal server error)
2710 # * partial support of the "linkage" MARC feature : if you enter a "link" on a MARC subfield, the magnifying glass won't search on the field, but on the linked field. I agree it's a partial support. Will be improved, but I need to investigate MARC21 & UNIMARC diffs on this topic.
2712 # Revision 1.113 2004/12/10 16:27:53 tipaul
2713 # limiting the number of search term to 8. There was no limit before, but 8 words seems to be the upper limit mySQL can deal with (in less than a second. tested on a DB with 13 000 items)
2714 # In 2.4, a new DB structure will highly speed things and this limit will be removed.
2715 # FindDuplicate is activated again, the perf problems were due to this problem.
2717 # Revision 1.112 2004/12/08 10:14:42 tipaul
2718 # * desactivate FindDuplicate
2721 # Revision 1.111 2004/11/25 17:39:44 tipaul
2722 # removing useless &branches in package declaration
2724 # Revision 1.110 2004/11/24 16:00:01 tipaul
2725 # removing sub branches (commited by chris for MARC=OFF bugfix, but sub branches is already in Acquisition.pm)
2727 # Revision 1.109 2004/11/24 15:58:31 tipaul
2728 # * critical fix for acquisition (see RC3 release notes)
2729 # * critical fix for duplicate finder
2731 # Revision 1.108 2004/11/19 19:41:22 rangi
2732 # Shifting branches() from deprecated C4::Catalogue to C4::Biblio
2733 # Allowing the non marc interface acquisitions to work.
2735 # Revision 1.107 2004/11/05 10:15:27 tipaul
2736 # Improving FindDuplicate to find duplicate records on adding biblio
2738 # Revision 1.106 2004/11/02 16:44:45 tipaul
2739 # new feature : checking for duplicate biblio.
2741 # For instance, it's only done on ISBN only. Will be improved soon.
2743 # When a duplicate is detected, the biblio is not saved, but the user is asked for a confirmations.
2745 # Revision 1.105 2004/09/23 16:15:37 tipaul
2748 # Revision 1.104 2004/09/16 15:06:46 tipaul
2749 # enabling # (| still possible too) for repeatable subfields
2751 # Revision 1.103 2004/09/06 14:17:34 tipaul
2752 # some commented warning added + 1 major bugfix => drop empty fields, NOT fields containing 0
2754 # Revision 1.102 2004/09/06 10:00:19 tipaul
2755 # adding a "location" field to the library.
2756 # This field is useful when the callnumber contains no information on the room where the item is stored.
2757 # With this field, we now have 3 levels of informations to find a book :
2762 # This should be versatile enough to solve any storing method.
2763 # This hack is quite simple, due to the nice Biblio.pm API. The MARC => koha db link is automatically managed. Just add the link in the parameters section.
2765 # Revision 1.101 2004/08/18 16:01:37 tipaul
2766 # modifs to support frameworkcodes
2768 # Revision 1.100 2004/08/13 16:37:25 tipaul
2769 # adding frameworkcode to API in some subs
2771 # Revision 1.99 2004/07/30 13:54:50 doxulting
2772 # Beginning of serial commit
2774 # Revision 1.98 2004/07/15 09:48:10 tipaul
2775 # * removing useless sub
2776 # * minor bugfix in moditem (managing homebranch & holdingbranch)
2778 # Revision 1.97 2004/07/02 15:53:53 tipaul
2779 # bugfix (due to frameworkcode field)
2781 # Revision 1.96 2004/06/29 16:07:10 tipaul
2782 # last sync for 2.1.0 release
2784 # Revision 1.95 2004/06/26 23:19:59 rangi
2785 # Fixing modaddauthor, and adding getitemtypes.
2786 # Also tidying up formatting of code
2788 # Revision 1.94 2004/06/17 08:16:32 tipaul
2789 # merging tag & subfield in marc_word for better perfs
2791 # Revision 1.93 2004/06/11 15:38:06 joshferraro
2792 # Changes MARCaddword to index words >= 1 char ... needed for more accurate
2793 # searches using SearchMarc routines.
2795 # Revision 1.92 2004/06/10 08:29:01 tipaul
2796 # MARC authority management (continued)
2798 # Revision 1.91 2004/06/03 10:03:01 tipaul
2799 # * frameworks and itemtypes are independant
2800 # * in the MARC editor, showing the + to duplicate a tag only if the tag is repeatable
2802 # Revision 1.90 2004/05/28 08:25:53 tipaul
2803 # hidding hidden & isurl constraints into MARC subfield structure
2805 # Revision 1.89 2004/05/27 21:47:21 rangi
2808 # Revision 1.88 2004/05/18 15:23:49 tipaul
2809 # framework management : 1 MARC framework for each itemtype
2811 # Revision 1.87 2004/05/18 11:54:07 tipaul
2812 # getitemtypes moved in Koha.pm
2814 # Revision 1.86 2004/05/03 09:19:22 tipaul
2815 # some fixes for mysql prepare & execute
2817 # Revision 1.85 2004/04/02 14:55:48 tipaul
2818 # renaming items.bulk field to items.itemcallnumber.
2819 # Will be used to store call number for libraries that don't use dewey classification.
2820 # Note it's related to ITEMS, not biblio.
2822 # Revision 1.84 2004/03/24 17:18:30 joshferraro
2823 # Fixes bug 749 by removing the comma on line 1488.
2825 # Revision 1.83 2004/03/15 14:31:50 tipaul
2826 # adding a minor check
2828 # Revision 1.82 2004/03/07 05:47:31 acli
2829 # Various updates/fixes from rel_2_0
2830 # Fixes for bugs 721 (templating), 727, and 734
2832 # Revision 1.81 2004/03/06 20:26:13 tipaul
2833 # adding seealso feature in MARC searches
2835 # Revision 1.80 2004/02/12 13:40:56 tipaul
2836 # deleting subs duplicated by error
2838 # Revision 1.79 2004/02/11 08:40:09 tipaul
2839 # synch'ing 2.0.0 branch and head
2841 # Revision 1.78.2.3 2004/02/10 13:15:46 tipaul
2842 # removing 2 warnings
2844 # Revision 1.78.2.2 2004/01/26 10:38:06 tipaul
2845 # dealing correctly "bulk" field
2847 # Revision 1.78.2.1 2004/01/13 17:29:53 tipaul
2848 # * minor html fixes
2849 # * adding publisher in acquisition process (& ordering basket by publisher)
2851 # Revision 1.78 2003/12/09 15:57:28 tipaul
2852 # rolling back to working char_decode sub
2854 # Revision 1.77 2003/12/03 17:47:14 tipaul
2855 # bugfixes for biblio deletion
2857 # Revision 1.76 2003/12/03 01:43:41 slef
2860 # Revision 1.75 2003/12/03 01:42:03 slef
2861 # bug 662 fixes securing DBI
2863 # Revision 1.74 2003/11/28 09:48:33 tipaul
2864 # bugfix : misusing prepare & execute => now using prepare(?) and execute($var)
2866 # Revision 1.73 2003/11/28 09:45:25 tipaul
2867 # bugfix for iso2709 file import in the "notforloan" field.
2869 # But notforloan field called "loan" somewhere, so in case "loan" is used, copied to "notforloan" to avoid a bug.
2871 # Revision 1.72 2003/11/24 17:40:14 tipaul
2874 # Revision 1.71 2003/11/24 16:28:49 tipaul
2875 # biblio & item deletion now works fine in MARC editor.
2876 # Stores deleted biblio/item in the marc field of the deletedbiblio/deleteditem table.
2878 # Revision 1.70 2003/11/24 13:29:55 tipaul
2879 # moving $id from beginning to end of file (70 commits... huge comments...)
2881 # Revision 1.69 2003/11/24 13:27:17 tipaul
2882 # fix for #380 (bibliosubject)
2884 # Revision 1.68 2003/11/06 17:18:30 tipaul
2887 # 1st draft for MARC biblio deletion.
2888 # Still does not work well, but at least, Biblio.pm compiles & it should'nt break too many things
2889 # (Note the trash in the MARCdetail, but don't use it, please :-) )
2891 # Revision 1.67 2003/10/25 08:46:27 tipaul
2892 # minor fixes for bilbio deletion (still buggy)
2894 # Revision 1.66 2003/10/17 10:02:56 tipaul
2895 # Indexing only words longer than 2 letters. Was >=2 before, & 2 letters words usually means nothing.
2897 # Revision 1.65 2003/10/14 09:45:29 tipaul
2898 # adding rebuildnonmarc.pl script : run this script when you change a link between marc and non MARC DB. It rebuilds the non-MARC DB (long operation)
2900 # Revision 1.64 2003/10/06 15:20:51 tipaul
2901 # fix for 536 (subtitle error)
2903 # Revision 1.63 2003/10/01 13:25:49 tipaul
2904 # seems a char encoding problem modified something in char_decode sub... changing back to something that works...
2906 # Revision 1.62 2003/09/17 14:21:13 tipaul
2907 # fixing bug that makes a MARC biblio disappear when using full acquisition (order => recieve ==> MARC editor).
2908 # Before this 2 lines fix, the MARC biblio was deleted during recieve, and had to be entirely recreated :-(
2910 # Revision 1.61 2003/09/17 10:24:39 tipaul
2911 # notforloan value in itemtype was overwritting notforloan value in a given item.
2912 # I changed this behaviour :
2913 # if notforloan is set for a given item, and NOT for all items from this itemtype, the notforloan is kept.
2914 # If notforloan is set for itemtype, it's used (and impossible to loan a specific item from this itemtype)
2916 # Revision 1.60 2003/09/04 14:11:23 tipaul
2917 # fix for 593 (data duplication in MARC-DB)
2919 # Revision 1.58 2003/08/06 12:54:52 tipaul
2920 # fix for publicationyear : extracting numeric value from MARC string, like for copyrightdate.
2921 # (note that copyrightdate still extracted to get numeric format)
2923 # Revision 1.57 2003/07/15 23:09:18 slef
2924 # change show columns to use biblioitems bnotes too
2926 # Revision 1.56 2003/07/15 11:34:52 slef
2927 # fixes from paul email
2929 # Revision 1.55 2003/07/15 00:02:49 slef
2930 # Work on bug 515... can we do a single-side rename of notes to bnotes?
2932 # Revision 1.54 2003/07/11 11:51:32 tipaul
2933 # *** empty log message ***
2935 # Revision 1.52 2003/07/10 10:37:19 tipaul
2936 # fix for copyrightdate problem, #514
2938 # Revision 1.51 2003/07/02 14:47:17 tipaul
2939 # fix for #519 : items.dateaccessioned imports incorrectly
2941 # Revision 1.49 2003/06/17 11:21:13 tipaul
2942 # improvments/fixes for z3950 support.
2943 # * Works now even on ADD, not only on MODIFY
2944 # * able to search on ISBN, author, title
2946 # Revision 1.48 2003/06/16 09:22:53 rangi
2947 # Just added an order clause to getitemtypes
2949 # Revision 1.47 2003/05/20 16:22:44 tipaul
2950 # fixing typo in Biblio.pm POD
2952 # Revision 1.46 2003/05/19 13:45:18 tipaul
2953 # support for subtitles, additional authors, subject.
2954 # This supports is only for MARC <-> OLD-DB link. It worked previously, but values entered as MARC were not reported to OLD-DB, neither values entered as OLD-DB were reported to MARC.
2955 # Note that some OLD-DB subs are strange (dummy ?) see OLDmodsubject, OLDmodsubtitle, OLDmodaddiauthor in C4/Biblio.pm
2956 # For example it seems impossible to have more that 1 addi author and 1 subtitle. In MARC it's not the case. So, if you enter more than one, I'm afraid only the LAST will be stored.
2958 # Revision 1.45 2003/04/29 16:50:49 tipaul
2959 # really proud of this commit :-)
2960 # z3950 search and import seems to works fine.
2961 # Let me explain how :
2962 # * a "search z3950" button is added in the addbiblio template.
2963 # * when clicked, a popup appears and z3950/search.pl is called
2964 # * z3950/search.pl calls addz3950search in the DB
2965 # * the z3950 daemon retrieve the records and stores them in z3950results AND in marc_breeding table.
2966 # * as long as there as searches pending, the popup auto refresh every 2 seconds, and says how many searches are pending.
2967 # * when the user clicks on a z3950 result => the parent popup is called with the requested biblio, and auto-filled
2970 # * character encoding support : (It's a nightmare...) In the z3950servers table, a "encoding" column has been added. You can put "UNIMARC" or "USMARC" in this column. Depending on this, the char_decode in C4::Biblio.pm replaces marc-char-encode by an iso 8859-1 encoding. Note that in the breeding import this value has been added too, for a better support.
2971 # * the marc_breeding and z3950* tables have been modified : they have an encoding column and the random z3950 number is stored too for convenience => it's the key I use to list only requested biblios in the popup.
2973 # Revision 1.44 2003/04/28 13:07:14 tipaul
2974 # Those fixes solves the "internal server error" with MARC::Record 1.12.
2975 # It was due to an illegal contruction in Koha : we tried to retrive subfields from <10 tags.
2976 # That's not possible. MARC::Record accepted this in 0.93 version, but it was fixed after.
2977 # Now, the construct/retrieving is OK !
2979 # Revision 1.43 2003/04/10 13:56:02 tipaul
2981 # * worked in 1.9.0, but not in 1.9.1 :
2982 # - modif of a biblio didn't work
2983 # - empty fields where not shown when modifying a biblio. empty fields managed by the library (ie in tab 0->9 in MARC parameter table) MUST be entered, even if not presented.
2985 # * did not work before :
2986 # - repeatable subfields now works correctly. Enter 2 subfields separated by | and they will be splitted during saving.
2987 # - dropped the last subfield of the MARC form :-(
2989 # Internal changes :
2990 # - MARCmodbiblio now works by deleting and recreating the biblio. It's not perf optimized, but MARC is a "do_something_impossible_to_trace" standard, so, it's the best solution. not a problem for me, as biblio are rarely modified.
2991 # Note the MARCdelbiblio has been rewritted to enable deletion of a biblio WITHOUT deleting items.
2993 # Revision 1.42 2003/04/04 08:41:11 tipaul
2994 # last commits before 1.9.1
2996 # Revision 1.41 2003/04/01 12:26:43 tipaul
2999 # Revision 1.40 2003/03/11 15:14:03 tipaul
3002 # Revision 1.39 2003/03/07 16:35:42 tipaul
3003 # * moving generic functions to Koha.pm
3004 # * improvement of SearchMarc.pm
3008 # Revision 1.38 2003/02/27 16:51:59 tipaul
3009 # * moving prepare / execute to ? form.
3012 # * road to 1.9.2 => acquisition and cataloguing merging
3014 # Revision 1.37 2003/02/12 11:03:03 tipaul
3015 # Support for 000 -> 010 fields.
3016 # Those fields doesn't have subfields.
3017 # In koha, we will use a specific "trick" : fields <10 will have a "virtual" subfield : "@".
3018 # Note it's only virtual : when rebuilding the MARC::Record, the koha API handle correctly "@" subfields => the resulting MARC record has a 00x field without subfield.
3020 # Revision 1.36 2003/02/12 11:01:01 tipaul
3021 # Support for 000 -> 010 fields.
3022 # Those fields doesn't have subfields.
3023 # In koha, we will use a specific "trick" : fields <10 will have a "virtual" subfield : "@".
3024 # Note it's only virtual : when rebuilding the MARC::Record, the koha API handle correctly "@" subfields => the resulting MARC record has a 00x field without subfield.
3026 # Revision 1.35 2003/02/03 18:46:00 acli
3027 # Minor factoring in C4/Biblio.pm, plus change to export the per-tag
3028 # 'mandatory' property to a per-subfield 'tag_mandatory' template parameter,
3029 # so that addbiblio.tmpl can distinguish between mandatory subfields in a
3030 # mandatory tag and mandatory subfields in an optional tag
3032 # Not-minor factoring in acqui.simple/addbiblio.pl to make the if-else blocks
3033 # smaller, and to add some POD; need further testing for this
3035 # Added function to check if a MARC subfield name is "koha-internal" (instead
3036 # of checking it for 'lib' and 'tag' everywhere); temporarily added to Koha.pm
3038 # Use above function in acqui.simple/additem.pl and search.marc/search.pl
3040 # Revision 1.34 2003/01/28 14:50:04 tipaul
3041 # fixing MARCmodbiblio API and reindenting code
3043 # Revision 1.33 2003/01/23 12:22:37 tipaul
3044 # adding char_decode to decode MARC21 or UNIMARC extended chars
3046 # Revision 1.32 2002/12/16 15:08:50 tipaul
3047 # small but important bugfix (fixes a problem in export)
3049 # Revision 1.31 2002/12/13 16:22:04 tipaul
3050 # 1st draft of marc export
3052 # Revision 1.30 2002/12/12 21:26:35 tipaul
3053 # YAB ! (Yet Another Bugfix) => related to biblio modif
3054 # (some warning cleaning too)
3056 # Revision 1.29 2002/12/12 16:35:00 tipaul
3057 # adding authentification with Auth.pm and
3058 # MAJOR BUGFIX on marc biblio modification
3060 # Revision 1.28 2002/12/10 13:30:03 tipaul
3061 # fugfixes from Dombes Abbey work
3063 # Revision 1.27 2002/11/19 12:36:16 tipaul
3065 # various bugfixes, improvments, and migration from acquisition.pm to biblio.pm
3067 # Revision 1.26 2002/11/12 15:58:43 tipaul
3070 # * adding value_builder : you can map a subfield in the marc_subfield_structure to a sub stored in "value_builder" directory. In this directory you can create screen used to build values with any method. In this commit is a 1st draft of the builder for 100$a unimarc french subfield, which is composed of 35 digits, with 12 differents values (only the 4th first are provided for instance)
3072 # Revision 1.25 2002/10/25 10:58:26 tipaul
3074 # * bugfixes and improvements
3076 # Revision 1.24 2002/10/24 12:09:01 arensb
3077 # Fixed "no title" warning when generating HTML documentation from POD.
3079 # Revision 1.23 2002/10/16 12:43:08 arensb
3080 # Added some FIXME comments.
3082 # Revision 1.22 2002/10/15 13:39:17 tipaul
3083 # removing Acquisition.pm
3084 # deleting unused code in biblio.pm, rewriting POD and answering most FIXME comments
3086 # Revision 1.21 2002/10/13 11:34:14 arensb
3087 # Replaced expressions of the form "$x = $x <op> $y" with "$x <op>= $y".
3088 # Thus, $x = $x+2 becomes $x += 2, and so forth.
3090 # Revision 1.20 2002/10/13 08:28:32 arensb
3091 # Deleted unused variables.
3092 # Removed trailing whitespace.
3094 # Revision 1.19 2002/10/13 05:56:10 arensb
3095 # Added some FIXME comments.
3097 # Revision 1.18 2002/10/11 12:34:53 arensb
3098 # Replaced &requireDBI with C4::Context->dbh
3100 # Revision 1.17 2002/10/10 14:48:25 tipaul
3103 # Revision 1.16 2002/10/07 14:04:26 tipaul
3104 # road to 1.3.1 : viewing MARC biblio
3106 # Revision 1.15 2002/10/05 09:49:25 arensb
3107 # Merged with arensb-context branch: use C4::Context->dbh instead of
3108 # &C4Connect, and generally prefer C4::Context over C4::Database.
3110 # Revision 1.14 2002/10/03 11:28:18 tipaul
3111 # Extending Context.pm to add stopword management and using it in MARC-API.
3112 # First benchmarks show a medium speed improvement, which is nice as this part is heavily called.
3114 # Revision 1.13 2002/10/02 16:26:44 tipaul
3117 # Revision 1.12.2.4 2002/10/05 07:09:31 arensb
3118 # Merged in changes from main branch.
3120 # Revision 1.12.2.3 2002/10/05 06:12:10 arensb
3121 # Added a whole mess of FIXME comments.
3123 # Revision 1.12.2.2 2002/10/05 04:03:14 arensb
3124 # Added some missing semicolons.
3126 # Revision 1.12.2.1 2002/10/04 02:24:01 arensb
3127 # Use C4::Connect instead of C4::Database, C4::Connect->dbh instead
3130 # Revision 1.12.2.3 2002/10/05 06:12:10 arensb
3131 # Added a whole mess of FIXME comments.
3133 # Revision 1.12.2.2 2002/10/05 04:03:14 arensb
3134 # Added some missing semicolons.
3136 # Revision 1.12.2.1 2002/10/04 02:24:01 arensb
3137 # Use C4::Connect instead of C4::Database, C4::Connect->dbh instead
3140 # Revision 1.12 2002/10/01 11:48:51 arensb
3141 # Added some FIXME comments, mostly marking duplicate functions.
3143 # Revision 1.11 2002/09/24 13:49:26 tipaul
3144 # long WAS the road to 1.3.0...
3145 # coming VERY SOON NOW...
3146 # modifying installer and buildrelease to update the DB
3148 # Revision 1.10 2002/09/22 16:50:08 arensb
3149 # Added some FIXME comments.
3151 # Revision 1.9 2002/09/20 12:57:46 tipaul
3152 # long is the road to 1.4.0
3153 # * MARCadditem and MARCmoditem now wroks
3154 # * various bugfixes in MARC management
3155 # !!! 1.3.0 should be released very soon now. Be careful !!!
3157 # Revision 1.8 2002/09/10 13:53:52 tipaul
3158 # MARC API continued...
3160 # * multiple item management : MARCadditem and MARCmoditem have been added. They suppose that ALL the MARC field linked to koha-item are in the same MARC tag (on the same line of MARC file)
3162 # Note : it should not be hard for marcimport and marcexport to re-link fields from internal tag/subfield to "legal" tag/subfield.
3164 # Revision 1.7 2002/08/14 18:12:51 tonnesen
3165 # Added copyright statement to all .pl and .pm files
3167 # Revision 1.6 2002/07/25 13:40:31 tipaul
3168 # pod documenting the API.
3170 # Revision 1.5 2002/07/24 16:11:37 tipaul
3172 # Database.pm and Output.pm are almost not modified (var test...)
3174 # Biblio.pm is almost completly rewritten.
3176 # WHAT DOES IT ??? ==> END of Hitchcock suspens
3178 # 1st, it does... nothing...
3179 # Every old API should be there. So if MARC-stuff is not done, the behaviour is EXACTLY the same (if there is no added bug, of course). So, if you use normal acquisition, you won't find anything new neither on screen or old-DB tables ...
3181 # All old-API functions have been cloned. for example, the "newbiblio" sub, now has become :
3182 # * a "newbiblio" sub, with the same parameters. It just call a sub named OLDnewbiblio
3183 # * a "OLDnewbiblio" sub, which is a copy/paste of the previous newbiblio sub. Then, when you want to add the MARC-DB stuff, you can modify the newbiblio sub without modifying the OLDnewbiblio one. If we correct a bug in 1.2 in newbiblio, we can do the same in main branch by correcting OLDnewbiblio.
3184 # * The MARC stuff is usually done through a sub named MARCxxx where xxx is the same as OLDxxx. For example, newbiblio calls MARCnewbiblio. the MARCxxx subs use a MARC::Record as parameter.
3185 # The last thing to solve was to manage biblios through real MARC import : they must populate the old-db, but must populate the MARC-DB too, without loosing information (if we go from MARC::Record to old-data then back to MARC::Record, we loose A LOT OF ROWS). To do this, there are subs beginning by "NEWxxx" : they manage datas with MARC::Record datas. they call OLDxxx sub too (to populate old-DB), but MARCxxx subs too, with a complete MARC::Record ;-)
3187 # In Biblio.pm, there are some subs that permits to build a old-style record from a MARC::Record, and the opposite. There is also a sub finding a MARC-bibid from a old-biblionumber and the opposite too.
3188 # Note we have decided with steve that a old-biblio <=> a MARC-Biblio.