3 # Copyright 2011 BibLibre
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
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 C4::OAI::Sets - OAI Sets management functions
26 C4::OAI::Sets contains functions for managing storage and editing of OAI Sets.
28 OAI Set description can be found L<here|http://www.openarchives.org/OAI/openarchivesprotocol.html#Set>
35 use vars qw(@ISA @EXPORT);
41 &GetOAISets &GetOAISet &GetOAISetBySpec &ModOAISet &DelOAISet &AddOAISet
42 &GetOAISetsMappings &GetOAISetMappings &ModOAISetMappings
43 &GetOAISetsBiblio &ModOAISetsBiblios &AddOAISetsBiblios
44 &CalcOAISetsBiblio &UpdateOAISetsBiblio
52 $oai_sets = GetOAISets;
54 GetOAISets return a array reference of hash references describing the sets.
55 The hash references looks like this:
70 my $dbh = C4::Context->dbh;
72 SELECT * FROM oai_sets
74 my $sth = $dbh->prepare($query);
76 my $results = $sth->fetchall_arrayref({});
80 FROM oai_sets_descriptions
83 $sth = $dbh->prepare($query);
84 foreach my $set (@$results) {
85 $sth->execute($set->{'id'});
86 my $desc = $sth->fetchall_arrayref({});
88 push @{$set->{'descriptions'}}, $_->{'description'};
97 $set = GetOAISet($set_id);
99 GetOAISet returns a hash reference describing the set with the given set_id.
101 See GetOAISets to see what the hash looks like.
108 return unless $set_id;
110 my $dbh = C4::Context->dbh;
116 my $sth = $dbh->prepare($query);
117 $sth->execute($set_id);
118 my $set = $sth->fetchrow_hashref;
122 FROM oai_sets_descriptions
125 $sth = $dbh->prepare($query);
126 $sth->execute($set->{'id'});
127 my $desc = $sth->fetchall_arrayref({});
129 push @{$set->{'descriptions'}}, $_->{'description'};
135 =head2 GetOAISetBySpec
137 my $set = GetOAISetBySpec($setSpec);
139 Returns a hash describing the set whose spec is $setSpec
143 sub GetOAISetBySpec {
146 return unless defined $setSpec;
148 my $dbh = C4::Context->dbh;
155 my $sth = $dbh->prepare($query);
156 $sth->execute($setSpec);
158 return $sth->fetchrow_hashref;
164 'id' => $set_id, # mandatory
165 'spec' => $spec, # mandatory
166 'name' => $name, # mandatory
167 'descriptions => \@descriptions, # optional, [] to remove descriptions
171 ModOAISet modify a set in the database.
178 return unless($set && $set->{'spec'} && $set->{'name'});
180 if(!defined $set->{'id'}) {
181 warn "Set ID not defined, can't modify the set";
185 my $dbh = C4::Context->dbh;
192 my $sth = $dbh->prepare($query);
193 $sth->execute($set->{'spec'}, $set->{'name'}, $set->{'id'});
195 if($set->{'descriptions'}) {
197 DELETE FROM oai_sets_descriptions
200 $sth = $dbh->prepare($query);
201 $sth->execute($set->{'id'});
203 if(scalar @{$set->{'descriptions'}} > 0) {
205 INSERT INTO oai_sets_descriptions (set_id, description)
208 $sth = $dbh->prepare($query);
209 foreach (@{ $set->{'descriptions'} }) {
210 $sth->execute($set->{'id'}, $_) if $_;
220 DelOAISet remove the set with the given set_id
227 return unless $set_id;
229 my $dbh = C4::Context->dbh;
231 DELETE oai_sets, oai_sets_descriptions, oai_sets_mappings
233 LEFT JOIN oai_sets_descriptions ON oai_sets_descriptions.set_id = oai_sets.id
234 LEFT JOIN oai_sets_mappings ON oai_sets_mappings.set_id = oai_sets.id
235 WHERE oai_sets.id = ?
237 my $sth = $dbh->prepare($query);
238 $sth->execute($set_id);
244 'id' => $set_id, # mandatory
245 'spec' => $spec, # mandatory
246 'name' => $name, # mandatory
247 'descriptions => \@descriptions, # optional
249 my $set_id = AddOAISet($set);
251 AddOAISet adds a new set and returns its id, or undef if something went wrong.
258 return unless($set && $set->{'spec'} && $set->{'name'});
261 my $dbh = C4::Context->dbh;
263 INSERT INTO oai_sets (spec, name)
266 my $sth = $dbh->prepare($query);
267 if( $sth->execute($set->{'spec'}, $set->{'name'}) ) {
268 $set_id = $dbh->last_insert_id(undef, undef, 'oai_sets', undef);
269 if($set->{'descriptions'}) {
271 INSERT INTO oai_sets_descriptions (set_id, description)
274 $sth = $dbh->prepare($query);
275 foreach( @{ $set->{'descriptions'} } ) {
276 $sth->execute($set_id, $_) if $_;
280 warn "AddOAISet failed";
286 =head2 GetOAISetsMappings
288 my $mappings = GetOAISetsMappings;
290 GetOAISetsMappings returns mappings for all OAI Sets.
292 Mappings define how biblios are categorized in sets.
293 A mapping is defined by three properties:
296 marcfield => 'XXX', # the MARC field to check
297 marcsubfield => 'Y', # the MARC subfield to check
298 marcvalue => 'zzzz', # the value to check
301 If defined in a set mapping, a biblio which have at least one 'Y' subfield of
302 one 'XXX' field equal to 'zzzz' will belong to this set.
303 If multiple mappings are defined in a set, the biblio will belong to this set
304 if at least one condition is matched.
306 GetOAISetsMappings returns a hashref of arrayrefs of hashrefs.
307 The first hashref keys are the sets IDs, so it looks like this:
327 sub GetOAISetsMappings {
328 my $dbh = C4::Context->dbh;
330 SELECT * FROM oai_sets_mappings
332 my $sth = $dbh->prepare($query);
336 while(my $result = $sth->fetchrow_hashref) {
337 push @{ $mappings->{$result->{'set_id'}} }, {
338 marcfield => $result->{'marcfield'},
339 marcsubfield => $result->{'marcsubfield'},
340 marcvalue => $result->{'marcvalue'}
347 =head2 GetOAISetMappings
349 my $set_mappings = GetOAISetMappings($set_id);
351 Return mappings for the set with given set_id. It's an arrayref of hashrefs
355 sub GetOAISetMappings {
358 return unless $set_id;
360 my $dbh = C4::Context->dbh;
363 FROM oai_sets_mappings
366 my $sth = $dbh->prepare($query);
367 $sth->execute($set_id);
370 while(my $result = $sth->fetchrow_hashref) {
372 marcfield => $result->{'marcfield'},
373 marcsubfield => $result->{'marcsubfield'},
374 marcvalue => $result->{'marcvalue'}
381 =head2 ModOAISetMappings {
391 ModOAISetMappings($set_id, $mappings);
393 ModOAISetMappings modifies mappings of a given set.
397 sub ModOAISetMappings {
398 my ($set_id, $mappings) = @_;
400 return unless $set_id;
402 my $dbh = C4::Context->dbh;
404 DELETE FROM oai_sets_mappings
407 my $sth = $dbh->prepare($query);
408 $sth->execute($set_id);
410 if(scalar @$mappings > 0) {
412 INSERT INTO oai_sets_mappings (set_id, marcfield, marcsubfield, marcvalue)
415 $sth = $dbh->prepare($query);
416 foreach (@$mappings) {
417 $sth->execute($set_id, $_->{'marcfield'}, $_->{'marcsubfield'}, $_->{'marcvalue'});
422 =head2 GetOAISetsBiblio
424 $oai_sets = GetOAISetsBiblio($biblionumber);
426 Return the OAI sets where biblio appears.
428 Return value is an arrayref of hashref where each element of the array is a set.
429 Keys of hash are id, spec and name
433 sub GetOAISetsBiblio {
434 my ($biblionumber) = @_;
436 my $dbh = C4::Context->dbh;
440 LEFT JOIN oai_sets_biblios ON oai_sets_biblios.set_id = oai_sets.id
441 WHERE biblionumber = ?
443 my $sth = $dbh->prepare($query);
445 $sth->execute($biblionumber);
446 return $sth->fetchall_arrayref({});
449 =head2 DelOAISetsBiblio
451 DelOAISetsBiblio($biblionumber);
453 Remove a biblio from all sets
457 sub DelOAISetsBiblio {
458 my ($biblionumber) = @_;
460 return unless $biblionumber;
462 my $dbh = C4::Context->dbh;
464 DELETE FROM oai_sets_biblios
465 WHERE biblionumber = ?
467 my $sth = $dbh->prepare($query);
468 return $sth->execute($biblionumber);
471 =head2 CalcOAISetsBiblio
473 my @sets = CalcOAISetsBiblio($record, $oai_sets_mappings);
475 Return a list of set ids the record belongs to. $record must be a MARC::Record
476 and $oai_sets_mappings (optional) must be a hashref returned by
481 sub CalcOAISetsBiblio {
482 my ($record, $oai_sets_mappings) = @_;
484 return unless $record;
486 $oai_sets_mappings ||= GetOAISetsMappings;
489 foreach my $set_id (keys %$oai_sets_mappings) {
490 foreach my $mapping (@{ $oai_sets_mappings->{$set_id} }) {
491 next if not $mapping;
492 my $field = $mapping->{'marcfield'};
493 my $subfield = $mapping->{'marcsubfield'};
494 my $value = $mapping->{'marcvalue'};
496 my @subfield_values = $record->subfield($field, $subfield);
497 if(0 < grep /^$value$/, @subfield_values) {
498 push @biblio_sets, $set_id;
506 =head2 ModOAISetsBiblios
508 my $oai_sets_biblios = {
509 '1' => [1, 3, 4], # key is the set_id, and value is an array ref of biblionumbers
513 ModOAISetsBiblios($oai_sets_biblios);
515 ModOAISetsBiblios truncate oai_sets_biblios table and call AddOAISetsBiblios.
516 This table is then used in opac/oai.pl.
520 sub ModOAISetsBiblios {
521 my $oai_sets_biblios = shift;
523 return unless ref($oai_sets_biblios) eq "HASH";
525 my $dbh = C4::Context->dbh;
527 TRUNCATE TABLE oai_sets_biblios
529 my $sth = $dbh->prepare($query);
531 AddOAISetsBiblios($oai_sets_biblios);
534 =head2 UpdateOAISetsBiblio
536 UpdateOAISetsBiblio($biblionumber, $record);
538 Update OAI sets for one biblio. The two parameters are mandatory.
539 $record is a MARC::Record.
543 sub UpdateOAISetsBiblio {
544 my ($biblionumber, $record) = @_;
546 return unless($biblionumber and $record);
549 my @sets = CalcOAISetsBiblio($record);
551 push @{ $sets_biblios->{$_} }, $biblionumber;
553 DelOAISetsBiblio($biblionumber);
554 AddOAISetsBiblios($sets_biblios);
557 =head2 AddOAISetsBiblios
559 my $oai_sets_biblios = {
560 '1' => [1, 3, 4], # key is the set_id, and value is an array ref of biblionumbers
564 ModOAISetsBiblios($oai_sets_biblios);
566 AddOAISetsBiblios insert given infos in oai_sets_biblios table.
567 This table is then used in opac/oai.pl.
571 sub AddOAISetsBiblios {
572 my $oai_sets_biblios = shift;
574 return unless ref($oai_sets_biblios) eq "HASH";
576 my $dbh = C4::Context->dbh;
578 INSERT INTO oai_sets_biblios (set_id, biblionumber)
581 my $sth = $dbh->prepare($query);
582 foreach my $set_id (keys %$oai_sets_biblios) {
583 foreach my $biblionumber (@{$oai_sets_biblios->{$set_id}}) {
584 $sth->execute($set_id, $biblionumber);