[Koha-patches] [PATCH] Bug 8844: UNIMARC_sync_date_created_with_marc_biblio.pl creates a modification log

Fridolyn SOMERS fridolyn.somers at biblibre.com
Fri Sep 28 18:46:08 CEST 2012


---
 .../UNIMARC_sync_date_created_with_marc_biblio.pl  |  237 +++++++++++++++++---
 1 file changed, 200 insertions(+), 37 deletions(-)

diff --git a/misc/maintenance/UNIMARC_sync_date_created_with_marc_biblio.pl b/misc/maintenance/UNIMARC_sync_date_created_with_marc_biblio.pl
index 43b5550..d271560 100755
--- a/misc/maintenance/UNIMARC_sync_date_created_with_marc_biblio.pl
+++ b/misc/maintenance/UNIMARC_sync_date_created_with_marc_biblio.pl
@@ -2,7 +2,7 @@
 #
 # This script should be used only with UNIMARC flavour
 # It is designed to report some missing information from biblio
-# table into  marc data
+# table into marc data
 #
 use strict;
 use warnings;
@@ -13,63 +13,226 @@ BEGIN {
 }
 
 use C4::Biblio;
+use Getopt::Long;
+
+sub _read_marc_code {
+    my $input = shift;
+    my ( $field, $subfield );
+    if ( $input =~ /^(\d{3})$/ ) {
+        $field    = $1;
+    } elsif ( $input =~ /^(\d{3})(\w)$/ ) {
+        $field    = $1;
+        $subfield = $2;
+    }
+    return ( $field, $subfield );
+}
+
+my ( $run, $help, $verbose, $where, $date_created_marc, $date_modified_marc );
+GetOptions(
+    'help|h'                 => \$help,
+    'verbose|v'              => \$verbose,
+    'run'                    => \$run,
+    'where:s'                => \$where,
+    'date-created-marc|c:s'  => \$date_created_marc,
+    'date-modified-marc|m:s' => \$date_modified_marc,
+);
+my $debug = $ENV{DEBUG};
+$verbose = 1 if $debug;
+
+# display help ?
+if ($help) {
+    print_usage();
+    exit 0;
+}
+
+$verbose and print "================================\n";
+
+# date created MARC field/subfield
+$date_created_marc = '099c' unless $date_created_marc;
+my ( $c_field, $c_subfield ) = _read_marc_code($date_created_marc);
+die "date-created-marc '$date_created_marc' is not correct." unless $c_field;
+if ($verbose) {
+    print "Date created on $c_field";
+    print $c_subfield if defined $c_subfield; # use of defined to allow 0
+    print "\n";
+}
+
+# date last modified MARC field/subfield
+$date_modified_marc = '099d' unless $date_modified_marc;
+my ( $m_field, $m_subfield ) = _read_marc_code($date_modified_marc);
+die "date-modified-marc '$date_modified_marc' is not correct." unless $m_field;
+die
+"When date-created-marc and date-modified-marc are on same field, they should have distinct subfields"
+  if ( $c_field eq $m_field )
+  && ( !defined $c_subfield
+    || !defined $m_subfield
+    || $c_subfield eq $m_subfield );
+if ($verbose) {
+    print "Date last modified on $m_field";
+    print $m_subfield if defined $m_subfield; # use of defined to allow 0
+    print "\n";
+}
+
+my $dbh;
+my $sth_prepared;
 
 sub updateMarc {
-    my $id = shift;
-    my $dbh = C4::Context->dbh;
-    my $field;
+    my $id     = shift;
     my $biblio = GetMarcBiblio($id);
 
-    return unless $biblio;
-
-    if(!$biblio->field('099'))
-    {
-        $field = new MARC::Field('099','','',
-                    'c' => '',
-                    'd'=>'');
-        $biblio->add_fields($field);
+    unless ($biblio) {
+        $debug and warn '[ERROR] GetMarcBiblio did not return any biblio.';
+        return;
     }
 
-    $field = $biblio->field('099');
+    my $c_marc_field = $biblio->field($c_field);
+    my $m_marc_field = $biblio->field($m_field);
 
-    my $sth = $dbh->prepare("SELECT DATE_FORMAT(datecreated,'%Y-%m-%d') as datecreated,
-                                    DATE_FORMAT(timestamp,'%Y-%m-%d') as timestamp,
-                                    frameworkcode
-                                    FROM biblio
-                                    WHERE biblionumber = ?");
-    $sth->execute($id);
-    (my $bibliorow = $sth->fetchrow_hashref);
+    my $c_marc_value;
+    if ($c_marc_field) {
+        $c_marc_value =
+          defined $c_subfield
+          ? $c_marc_field->subfield($c_subfield)
+          : $c_marc_field->data();
+    }
+    $c_marc_value = '' unless defined $c_marc_value;
+
+    my $m_marc_value;
+    if ($m_marc_field) {
+        $m_marc_value =
+          defined $m_subfield
+          ? $m_marc_field->subfield($m_subfield)
+          : $m_marc_field->data();
+    }
+    $m_marc_value ||= '';
+
+    $sth_prepared = $dbh->prepare(
+        q{
+        SELECT
+            DATE_FORMAT(datecreated,'%Y-%m-%d') AS datecreatediso,
+            DATE_FORMAT(timestamp,'%Y-%m-%d') AS datemodifiediso,
+            frameworkcode
+        FROM biblio
+        WHERE biblionumber = ?
+    }
+    ) unless $sth_prepared;
+    $sth_prepared->execute($id);
+    my $bibliorow     = $sth_prepared->fetchrow_hashref;
     my $frameworkcode = $bibliorow->{'frameworkcode'};
+    my $c_db_value    = $bibliorow->{'datecreatediso'} || '';
+    my $m_db_value    = $bibliorow->{'datemodifiediso'} || '';
 
-    $field->update( 'c' => $bibliorow->{'datecreated'},
-                    'd' => $bibliorow->{'timestamp'}
-                    );
+    # do nothing if already sync
+    return if ( $c_marc_value eq $c_db_value && $m_marc_value eq $m_db_value );
 
-     if(&ModBiblio($biblio, $id, $frameworkcode))
-     {
-        print "\r$id";
-     }
+    # do apply to database ?
+    return 1 unless $run;
 
+    # update MARC record
+
+    # date created field
+    if ($c_marc_field) {
+        if ( defined $c_subfield ) {
+            $c_marc_field->update( $c_subfield, $c_db_value );
+        }
+        else {
+            $c_marc_field->update($c_db_value);
+        }
+    }
+    else {
+        $c_marc_field =
+          new MARC::Field( $c_field, '', '', $c_subfield => $c_db_value, );
+        $biblio->add_fields($c_marc_field);
+        $debug and warn "[WARN] $c_field did not exist.";
+
+        # when on same field
+        if ( $m_field eq $c_field ) {
+            $m_marc_field = $c_marc_field;
+        }
+    }
+
+    # date last modified field
+    if ($m_marc_field) {
+        if ( defined $m_subfield ) {
+            $m_marc_field->update( $m_subfield, $m_db_value );
+        }
+        else {
+            $m_marc_field->update($m_db_value);
+        }
+    }
+    else {
+        $m_marc_field =
+          new MARC::Field( $m_field, '', '', $m_subfield => $m_db_value, );
+        $biblio->add_fields($m_marc_field);
+        $debug and warn "[WARN] $m_field did not exist.";
+    }
+
+    # apply to databse
+    if ( &ModBiblio( $biblio, $id, $frameworkcode ) ) {
+        return 1;
+    }
+
+    $debug and warn '[ERROR] ModBiblio failed.';
+    return;
 }
 
 sub process {
 
-    my $dbh = C4::Context->dbh;
+    $dbh = C4::Context->dbh;
+    my $mod_count = 0;
 
-    my $sth = $dbh->prepare("SELECT biblionumber FROM biblio");
+    my $query = q{
+        SELECT biblionumber
+        FROM biblio
+        JOIN biblioitems USING (biblionumber)
+    };
+    $query .= qq{ WHERE $where} if $where;
+    my $sth = $dbh->prepare($query);
     $sth->execute();
 
-    while(my $biblios = $sth->fetchrow_hashref)
-    {
-        updateMarc($biblios->{'biblionumber'});
-        print ".";
+    $verbose and print "Number of concerned biblios: " . $sth->rows . "\n";
+
+    while ( my $biblios = $sth->fetchrow_hashref ) {
+        $verbose and print 'Bib ' . $biblios->{'biblionumber'} . ':';
+        my $ret = updateMarc( $biblios->{'biblionumber'} );
+        if ($ret) {
+            $verbose and print 'modified';
+            $mod_count++;
+        }
+        $verbose and print "\n";
     }
 
+    $verbose and print "Number of modified biblios: " . $mod_count . "\n";
 }
 
-if (lc(C4::Context->preference('marcflavour')) eq "unimarc"){
-process();
-} 
+if ( lc( C4::Context->preference('marcflavour') ) eq "unimarc" ) {
+    $verbose
+      and !$run
+      and print "*** Not in run mode, modifications will not be applyed ***\n";
+
+    $verbose and print "================================\n";
+    process();
+}
 else {
-	print "this script is UNIMARC only and should be used only on unimarc databases\n";
+    print
+"This script is UNIMARC only and should be used only on UNIMARC databases\n";
+}
+
+sub print_usage {
+    print <<_USAGE_;
+Synchronizes date created and date last modified from biblio table to MARC data.
+Does not update biblio if dates are already synchronized.
+UNIMARC specific.
+
+Parameters:
+    --help or -h                show this message
+    --verbose or -v             verbose logging
+    --run                       run the command else modifications will not be applyed to database
+    --where                     (optional) use this to limit execution to some biblios :
+                                write a SQL where clause using biblio and/or biblioitems fields
+    --date-created-marc or c    (optional) date created MARC field and optional subfield,
+                                099c by default
+    --date-modified-marc or m   (optional) date last modified MARC field and optional subfield,
+                                099d by default
+_USAGE_
 }
-- 
1.7.9.5



More information about the Koha-patches mailing list