4cf30123a4
don't update your cvs if you want to have a working head... this commit contains : * 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... * 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. * other files : get rid of bibid and use biblionumber instead. What is broken : * does not do anything on zebra yet. * if you rename marc_subfield_table, you can't search anymore. * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif. * 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 ;-) ) 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 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.
682 lines
24 KiB
Perl
Executable file
682 lines
24 KiB
Perl
Executable file
#!/usr/bin/perl
|
|
|
|
# $Id$
|
|
|
|
# Database Updater
|
|
# This script checks for required updates to the database.
|
|
|
|
# Part of the Koha Library Software www.koha.org
|
|
# Licensed under the GPL.
|
|
|
|
# Bugs/ToDo:
|
|
# - Would also be a good idea to offer to do a backup at this time...
|
|
|
|
# NOTE: If you do something more than once in here, make it table driven.
|
|
use strict;
|
|
|
|
# CPAN modules
|
|
use DBI;
|
|
use Getopt::Long;
|
|
# Koha modules
|
|
use C4::Context;
|
|
|
|
use MARC::Record;
|
|
use MARC::File::XML;
|
|
|
|
# FIXME - The user might be installing a new database, so can't rely
|
|
# on /etc/koha.conf anyway.
|
|
|
|
my $debug = 0;
|
|
|
|
my (
|
|
$sth, $sti,
|
|
$query,
|
|
%existingtables, # tables already in database
|
|
%types,
|
|
$table,
|
|
$column,
|
|
$type, $null, $key, $default, $extra,
|
|
$prefitem, # preference item in systempreferences table
|
|
);
|
|
|
|
my $silent;
|
|
GetOptions(
|
|
's' =>\$silent
|
|
);
|
|
my $dbh = C4::Context->dbh;
|
|
print "connected to your DB. Checking & modifying it\n" unless $silent;
|
|
$|=1; # flushes output
|
|
|
|
#-------------------
|
|
# Defines
|
|
|
|
# Tables to add if they don't exist
|
|
my %requiretables = (
|
|
categorytable => "(categorycode char(5) NOT NULL default '',
|
|
description text default '',
|
|
itemtypecodes text default '',
|
|
PRIMARY KEY (categorycode)
|
|
)",
|
|
subcategorytable => "(subcategorycode char(5) NOT NULL default '',
|
|
description text default '',
|
|
itemtypecodes text default '',
|
|
PRIMARY KEY (subcategorycode)
|
|
)",
|
|
mediatypetable => "(mediatypecode char(5) NOT NULL default '',
|
|
description text default '',
|
|
itemtypecodes text default '',
|
|
PRIMARY KEY (mediatypecode)
|
|
)",
|
|
action_logs => "(
|
|
`timestamp` TIMESTAMP NOT NULL ,
|
|
`user` INT( 11 ) NOT NULL ,
|
|
`module` TEXT default '',
|
|
`action` TEXT default '' ,
|
|
`object` INT(11) default '' ,
|
|
`info` TEXT default '' ,
|
|
PRIMARY KEY ( `timestamp` , `user` )
|
|
)",
|
|
letter => "(
|
|
module varchar(20) NOT NULL default '',
|
|
code varchar(20) NOT NULL default '',
|
|
name varchar(100) NOT NULL default '',
|
|
title varchar(200) NOT NULL default '',
|
|
content text,
|
|
PRIMARY KEY (module,code)
|
|
)",
|
|
alert =>"(
|
|
alertid int(11) NOT NULL auto_increment,
|
|
borrowernumber int(11) NOT NULL default '0',
|
|
type varchar(10) NOT NULL default '',
|
|
externalid varchar(20) NOT NULL default '',
|
|
PRIMARY KEY (alertid),
|
|
KEY borrowernumber (borrowernumber),
|
|
KEY type (type,externalid)
|
|
)",
|
|
|
|
);
|
|
|
|
my %requirefields = (
|
|
subscription => { 'letter' => 'char(20) NULL'},
|
|
# tablename => { 'field' => 'fieldtype' },
|
|
);
|
|
|
|
my %dropable_table = (
|
|
# tablename => 'tablename',
|
|
);
|
|
|
|
my %uselessfields = (
|
|
# tablename => "field1,field2",
|
|
);
|
|
# the other hash contains other actions that can't be done elsewhere. they are done
|
|
# either BEFORE of AFTER everything else, depending on "when" entry (default => AFTER)
|
|
|
|
# The tabledata hash contains data that should be in the tables.
|
|
# The uniquefieldrequired hash entry is used to determine which (if any) fields
|
|
# must not exist in the table for this row to be inserted. If the
|
|
# uniquefieldrequired entry is already in the table, the existing data is not
|
|
# modified, unless the forceupdate hash entry is also set. Fields in the
|
|
# anonymous "forceupdate" hash will be forced to be updated to the default
|
|
# values given in the %tabledata hash.
|
|
|
|
my %tabledata = (
|
|
# tablename => [
|
|
# { uniquefielrequired => 'fieldname', # the primary key in the table
|
|
# fieldname => fieldvalue,
|
|
# fieldname2 => fieldvalue2,
|
|
# },
|
|
# ],
|
|
systempreferences => [
|
|
{
|
|
uniquefieldrequired => 'variable',
|
|
variable => 'Activate_Log',
|
|
value => 'On',
|
|
forceupdate => { 'explanation' => 1,
|
|
'type' => 1},
|
|
explanation => 'Turn Log Actions on DB On an Off',
|
|
type => 'YesNo',
|
|
},
|
|
{
|
|
uniquefieldrequired => 'variable',
|
|
variable => 'IndependantBranches',
|
|
value => 0,
|
|
forceupdate => { 'explanation' => 1,
|
|
'type' => 1},
|
|
explanation => 'Turn Branch independancy management On an Off',
|
|
type => 'YesNo',
|
|
},
|
|
{
|
|
uniquefieldrequired => 'variable',
|
|
variable => 'ReturnBeforeExpiry',
|
|
value => 'Off',
|
|
forceupdate => { 'explanation' => 1,
|
|
'type' => 1},
|
|
explanation => 'If Yes, Returndate on issuing can\'t be after borrower card expiry',
|
|
type => 'YesNo',
|
|
},
|
|
],
|
|
|
|
);
|
|
|
|
my %fielddefinitions = (
|
|
# fieldname => [
|
|
# { field => 'fieldname',
|
|
# type => 'fieldtype',
|
|
# null => '',
|
|
# key => '',
|
|
# default => ''
|
|
# },
|
|
# ],
|
|
);
|
|
|
|
#-------------------
|
|
# Initialize
|
|
|
|
# Start checking
|
|
|
|
# Get version of MySQL database engine.
|
|
my $mysqlversion = `mysqld --version`;
|
|
$mysqlversion =~ /Ver (\S*) /;
|
|
$mysqlversion = $1;
|
|
if ( $mysqlversion ge '3.23' ) {
|
|
print "Could convert to MyISAM database tables...\n" unless $silent;
|
|
}
|
|
|
|
#---------------------------------
|
|
# Tables
|
|
|
|
# Collect all tables into a list
|
|
$sth = $dbh->prepare("show tables");
|
|
$sth->execute;
|
|
while ( my ($table) = $sth->fetchrow ) {
|
|
$existingtables{$table} = 1;
|
|
}
|
|
|
|
|
|
# Now add any missing tables
|
|
foreach $table ( keys %requiretables ) {
|
|
unless ( $existingtables{$table} ) {
|
|
print "Adding $table table...\n" unless $silent;
|
|
my $sth = $dbh->prepare("create table $table $requiretables{$table}");
|
|
$sth->execute;
|
|
if ( $sth->err ) {
|
|
print "Error : $sth->errstr \n";
|
|
$sth->finish;
|
|
} # if error
|
|
} # unless exists
|
|
} # foreach
|
|
|
|
# now drop useless tables
|
|
foreach $table ( keys %dropable_table ) {
|
|
if ( $existingtables{$table} ) {
|
|
print "Dropping unused table $table\n" if $debug and not $silent;
|
|
$dbh->do("drop table $table");
|
|
if ( $dbh->err ) {
|
|
print "Error : $dbh->errstr \n";
|
|
}
|
|
}
|
|
}
|
|
|
|
#---------------------------------
|
|
# Columns
|
|
|
|
foreach $table ( keys %requirefields ) {
|
|
print "Check table $table\n" if $debug and not $silent;
|
|
$sth = $dbh->prepare("show columns from $table");
|
|
$sth->execute();
|
|
undef %types;
|
|
while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
|
|
{
|
|
$types{$column} = $type;
|
|
} # while
|
|
foreach $column ( keys %{ $requirefields{$table} } ) {
|
|
print " Check column $column [$types{$column}]\n" if $debug and not $silent;
|
|
if ( !$types{$column} ) {
|
|
|
|
# column doesn't exist
|
|
print "Adding $column field to $table table...\n" unless $silent;
|
|
$query = "alter table $table
|
|
add column $column " . $requirefields{$table}->{$column};
|
|
print "Execute: $query\n" if $debug;
|
|
my $sti = $dbh->prepare($query);
|
|
$sti->execute;
|
|
if ( $sti->err ) {
|
|
print "**Error : $sti->errstr \n";
|
|
$sti->finish;
|
|
} # if error
|
|
} # if column
|
|
} # foreach column
|
|
} # foreach table
|
|
|
|
foreach $table ( keys %fielddefinitions ) {
|
|
print "Check table $table\n" if $debug;
|
|
$sth = $dbh->prepare("show columns from $table");
|
|
$sth->execute();
|
|
my $definitions;
|
|
while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
|
|
{
|
|
$definitions->{$column}->{type} = $type;
|
|
$definitions->{$column}->{null} = $null;
|
|
$definitions->{$column}->{key} = $key;
|
|
$definitions->{$column}->{default} = $default;
|
|
$definitions->{$column}->{extra} = $extra;
|
|
} # while
|
|
my $fieldrow = $fielddefinitions{$table};
|
|
foreach my $row (@$fieldrow) {
|
|
my $field = $row->{field};
|
|
my $type = $row->{type};
|
|
my $null = $row->{null};
|
|
my $key = $row->{key};
|
|
my $default = $row->{default};
|
|
$default="''" unless $default;
|
|
my $extra = $row->{extra};
|
|
my $def = $definitions->{$field};
|
|
unless ( $type eq $def->{type}
|
|
&& $null eq $def->{null}
|
|
&& $key eq $def->{key}
|
|
&& $default eq $def->{default}
|
|
&& $extra eq $def->{extra} )
|
|
{
|
|
|
|
if ( $null eq '' ) {
|
|
$null = 'NOT NULL';
|
|
}
|
|
if ( $key eq 'PRI' ) {
|
|
$key = 'PRIMARY KEY';
|
|
}
|
|
unless ( $extra eq 'auto_increment' ) {
|
|
$extra = '';
|
|
}
|
|
# if it's a new column use "add", if it's an old one, use "change".
|
|
my $action;
|
|
if ($definitions->{$field}->{type}) {
|
|
$action="change $field"
|
|
} else {
|
|
$action="add";
|
|
}
|
|
# if it's a primary key, drop the previous pk, before altering the table
|
|
my $sth;
|
|
if ($key ne 'PRIMARY KEY') {
|
|
$sth =$dbh->prepare("alter table $table $action $field $type $null $key $extra default ?");
|
|
} else {
|
|
$sth =$dbh->prepare("alter table $table drop primary key, $action $field $type $null $key $extra default ?");
|
|
}
|
|
$sth->execute($default);
|
|
print " Alter $field in $table\n" unless $silent;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
# Populate tables with required data
|
|
foreach my $table ( keys %tabledata ) {
|
|
print "Checking for data required in table $table...\n" unless $silent;
|
|
my $tablerows = $tabledata{$table};
|
|
foreach my $row (@$tablerows) {
|
|
my $uniquefieldrequired = $row->{uniquefieldrequired};
|
|
my $uniquevalue = $row->{$uniquefieldrequired};
|
|
my $forceupdate = $row->{forceupdate};
|
|
my $sth =
|
|
$dbh->prepare(
|
|
"select $uniquefieldrequired from $table where $uniquefieldrequired=?"
|
|
);
|
|
$sth->execute($uniquevalue);
|
|
if ($sth->rows) {
|
|
foreach my $field (keys %$forceupdate) {
|
|
if ($forceupdate->{$field}) {
|
|
my $sth=$dbh->prepare("update systempreferences set $field=? where $uniquefieldrequired=?");
|
|
$sth->execute($row->{$field}, $uniquevalue);
|
|
}
|
|
}
|
|
} else {
|
|
print "Adding row to $table: " unless $silent;
|
|
my @values;
|
|
my $fieldlist;
|
|
my $placeholders;
|
|
foreach my $field ( keys %$row ) {
|
|
next if $field eq 'uniquefieldrequired';
|
|
next if $field eq 'forceupdate';
|
|
my $value = $row->{$field};
|
|
push @values, $value;
|
|
print " $field => $value" unless $silent;
|
|
$fieldlist .= "$field,";
|
|
$placeholders .= "?,";
|
|
}
|
|
print "\n" unless $silent;
|
|
$fieldlist =~ s/,$//;
|
|
$placeholders =~ s/,$//;
|
|
my $sth =
|
|
$dbh->prepare(
|
|
"insert into $table ($fieldlist) values ($placeholders)");
|
|
$sth->execute(@values);
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# SPECIFIC STUFF
|
|
#
|
|
#
|
|
# create frameworkcode row in biblio table & fill it with marc_biblio.frameworkcode.
|
|
#
|
|
|
|
# 1st, get how many biblio we will have to do...
|
|
$sth = $dbh->prepare('select count(*) from marc_biblio');
|
|
$sth->execute;
|
|
my ($totaltodo) = $sth->fetchrow;
|
|
|
|
$sth = $dbh->prepare("show columns from biblio");
|
|
$sth->execute();
|
|
my $definitions;
|
|
my $bibliofwexist=0;
|
|
while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ){
|
|
$bibliofwexist=1 if $column eq 'frameworkcode';
|
|
}
|
|
unless ($bibliofwexist) {
|
|
print "moving biblioframework to biblio table\n";
|
|
$dbh->do('ALTER TABLE `biblio` ADD `frameworkcode` VARCHAR( 4 ) NOT NULL AFTER `biblionumber`');
|
|
$sth = $dbh->prepare('select biblionumber,frameworkcode from marc_biblio');
|
|
$sth->execute;
|
|
my $sth_update = $dbh->prepare('update biblio set frameworkcode=? where biblionumber=?');
|
|
my $totaldone=0;
|
|
while (my ($biblionumber,$frameworkcode) = $sth->fetchrow) {
|
|
$sth_update->execute($frameworkcode,$biblionumber);
|
|
$totaldone++;
|
|
print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
|
|
}
|
|
print "\rdone\n";
|
|
}
|
|
|
|
#
|
|
# moving MARC data from marc_subfield_table to biblioitems.marc
|
|
#
|
|
$sth = $dbh->prepare("show columns from biblioitems");
|
|
$sth->execute();
|
|
my $definitions;
|
|
my $marcdone=0;
|
|
while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ){
|
|
$marcdone=1 if ($type eq 'blob' && $column eq 'marc') ;
|
|
}
|
|
unless ($marcdone) {
|
|
print "moving MARC record to biblioitems table\n";
|
|
# changing marc field type
|
|
$dbh->do('ALTER TABLE `biblioitems` CHANGE `marc` `marc` BLOB NULL DEFAULT NULL ');
|
|
# adding marc xml, just for convenience
|
|
$dbh->do('ALTER TABLE `biblioitems` ADD `marcxml` TEXT NOT NULL');
|
|
# moving data from marc_subfield_value to biblio
|
|
$sth = $dbh->prepare('select bibid,biblionumber from marc_biblio');
|
|
$sth->execute;
|
|
my $sth_update = $dbh->prepare('update biblioitems set marc=?, marcxml=? where biblionumber=?');
|
|
my $totaldone=0;
|
|
while (my ($bibid,$biblionumber) = $sth->fetchrow) {
|
|
my $record = MARCgetbiblio($dbh,$bibid);
|
|
$sth_update->execute($record->as_usmarc(),$record->as_xml(),$biblionumber);
|
|
$totaldone++;
|
|
print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
|
|
}
|
|
print "\rdone\n";
|
|
}
|
|
|
|
# at last, remove useless fields
|
|
foreach $table ( keys %uselessfields ) {
|
|
my @fields = split /,/,$uselessfields{$table};
|
|
my $fields;
|
|
my $exists;
|
|
foreach my $fieldtodrop (@fields) {
|
|
$fieldtodrop =~ s/\t//g;
|
|
$fieldtodrop =~ s/\n//g;
|
|
$exists =0;
|
|
$sth = $dbh->prepare("show columns from $table");
|
|
$sth->execute;
|
|
while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
|
|
{
|
|
$exists =1 if ($column eq $fieldtodrop);
|
|
}
|
|
if ($exists) {
|
|
print "deleting $fieldtodrop field in $table...\n" unless $silent;
|
|
my $sth = $dbh->prepare("alter table $table drop $fieldtodrop");
|
|
$sth->execute;
|
|
}
|
|
}
|
|
} # foreach
|
|
|
|
|
|
$sth->finish;
|
|
|
|
#
|
|
# those 2 subs are a copy of Biblio.pm, version 2.2.4
|
|
# they are useful only once, for moving from 2.2 to 3.0
|
|
# the MARCgetbiblio & MARCgetitem subs in Biblio.pm
|
|
# are still here, but uses other tables
|
|
# (the ones that are filled by updatedatabase !)
|
|
#
|
|
sub MARCgetbiblio {
|
|
|
|
# Returns MARC::Record of the biblio passed in parameter.
|
|
my ( $dbh, $bibid ) = @_;
|
|
my $record = MARC::Record->new();
|
|
# warn "". $bidid;
|
|
|
|
my $sth =
|
|
$dbh->prepare(
|
|
"select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
|
|
from marc_subfield_table
|
|
where bibid=? order by tag,tagorder,subfieldorder
|
|
"
|
|
);
|
|
my $sth2 =
|
|
$dbh->prepare(
|
|
"select subfieldvalue from marc_blob_subfield where blobidlink=?");
|
|
$sth->execute($bibid);
|
|
my $prevtagorder = 1;
|
|
my $prevtag = 'XXX';
|
|
my $previndicator;
|
|
my $field; # for >=10 tags
|
|
my $prevvalue; # for <10 tags
|
|
while ( my $row = $sth->fetchrow_hashref ) {
|
|
|
|
if ( $row->{'valuebloblink'} ) { #---- search blob if there is one
|
|
$sth2->execute( $row->{'valuebloblink'} );
|
|
my $row2 = $sth2->fetchrow_hashref;
|
|
$sth2->finish;
|
|
$row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
|
|
}
|
|
if ( $row->{tagorder} ne $prevtagorder || $row->{tag} ne $prevtag ) {
|
|
$previndicator .= " ";
|
|
if ( $prevtag < 10 ) {
|
|
if ($prevtag ne '000') {
|
|
$record->add_fields( ( sprintf "%03s", $prevtag ), $prevvalue ) unless $prevtag eq "XXX"; # ignore the 1st loop
|
|
} else {
|
|
$record->leader(sprintf("%24s",$prevvalue));
|
|
}
|
|
}
|
|
else {
|
|
$record->add_fields($field) unless $prevtag eq "XXX";
|
|
}
|
|
undef $field;
|
|
$prevtagorder = $row->{tagorder};
|
|
$prevtag = $row->{tag};
|
|
$previndicator = $row->{tag_indicator};
|
|
if ( $row->{tag} < 10 ) {
|
|
$prevvalue = $row->{subfieldvalue};
|
|
}
|
|
else {
|
|
$field = MARC::Field->new(
|
|
( sprintf "%03s", $prevtag ),
|
|
substr( $row->{tag_indicator} . ' ', 0, 1 ),
|
|
substr( $row->{tag_indicator} . ' ', 1, 1 ),
|
|
$row->{'subfieldcode'},
|
|
$row->{'subfieldvalue'}
|
|
);
|
|
}
|
|
}
|
|
else {
|
|
if ( $row->{tag} < 10 ) {
|
|
$record->add_fields( ( sprintf "%03s", $row->{tag} ),
|
|
$row->{'subfieldvalue'} );
|
|
}
|
|
else {
|
|
$field->add_subfields( $row->{'subfieldcode'},
|
|
$row->{'subfieldvalue'} );
|
|
}
|
|
$prevtag = $row->{tag};
|
|
$previndicator = $row->{tag_indicator};
|
|
}
|
|
}
|
|
|
|
# the last has not been included inside the loop... do it now !
|
|
if ( $prevtag ne "XXX" )
|
|
{ # check that we have found something. Otherwise, prevtag is still XXX and we
|
|
# must return an empty record, not make MARC::Record fail because we try to
|
|
# create a record with XXX as field :-(
|
|
if ( $prevtag < 10 ) {
|
|
$record->add_fields( $prevtag, $prevvalue );
|
|
}
|
|
else {
|
|
|
|
# my $field = MARC::Field->new( $prevtag, "", "", %subfieldlist);
|
|
$record->add_fields($field);
|
|
}
|
|
}
|
|
return $record;
|
|
}
|
|
|
|
sub MARCgetitem {
|
|
|
|
# Returns MARC::Record of the biblio passed in parameter.
|
|
my ( $dbh, $bibid, $itemnumber ) = @_;
|
|
my $record = MARC::Record->new();
|
|
|
|
# search MARC tagorder
|
|
my $sth2 =
|
|
$dbh->prepare(
|
|
"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=?"
|
|
);
|
|
$sth2->execute( $bibid, $itemnumber );
|
|
my ($tagorder) = $sth2->fetchrow_array();
|
|
|
|
#---- TODO : the leader is missing
|
|
my $sth =
|
|
$dbh->prepare(
|
|
"select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
|
|
from marc_subfield_table
|
|
where bibid=? and tagorder=? order by subfieldcode,subfieldorder
|
|
"
|
|
);
|
|
$sth2 =
|
|
$dbh->prepare(
|
|
"select subfieldvalue from marc_blob_subfield where blobidlink=?");
|
|
$sth->execute( $bibid, $tagorder );
|
|
while ( my $row = $sth->fetchrow_hashref ) {
|
|
if ( $row->{'valuebloblink'} ) { #---- search blob if there is one
|
|
$sth2->execute( $row->{'valuebloblink'} );
|
|
my $row2 = $sth2->fetchrow_hashref;
|
|
$sth2->finish;
|
|
$row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
|
|
}
|
|
if ( $record->field( $row->{'tag'} ) ) {
|
|
my $field;
|
|
|
|
#--- this test must stay as this, because of strange behaviour of mySQL/Perl DBI with char var containing a number...
|
|
#--- sometimes, eliminates 0 at beginning, sometimes no ;-\\\
|
|
if ( length( $row->{'tag'} ) < 3 ) {
|
|
$row->{'tag'} = "0" . $row->{'tag'};
|
|
}
|
|
$field = $record->field( $row->{'tag'} );
|
|
if ($field) {
|
|
my $x =
|
|
$field->add_subfields( $row->{'subfieldcode'},
|
|
$row->{'subfieldvalue'} );
|
|
$record->delete_field($field);
|
|
$record->add_fields($field);
|
|
}
|
|
}
|
|
else {
|
|
if ( length( $row->{'tag'} ) < 3 ) {
|
|
$row->{'tag'} = "0" . $row->{'tag'};
|
|
}
|
|
my $temp =
|
|
MARC::Field->new( $row->{'tag'}, " ", " ",
|
|
$row->{'subfieldcode'} => $row->{'subfieldvalue'} );
|
|
$record->add_fields($temp);
|
|
}
|
|
|
|
}
|
|
return $record;
|
|
}
|
|
|
|
|
|
exit;
|
|
|
|
# $Log$
|
|
# Revision 1.120 2005/08/09 14:10:32 tipaul
|
|
# 1st commit to go to zebra.
|
|
# don't update your cvs if you want to have a working head...
|
|
#
|
|
# this commit contains :
|
|
# * 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...
|
|
# * 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.
|
|
# * other files : get rid of bibid and use biblionumber instead.
|
|
#
|
|
# What is broken :
|
|
# * does not do anything on zebra yet.
|
|
# * if you rename marc_subfield_table, you can't search anymore.
|
|
# * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
|
|
# * 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 ;-) )
|
|
#
|
|
# 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
|
|
# 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.
|
|
#
|
|
# Revision 1.119 2005/08/04 16:07:58 tipaul
|
|
# Synch really broke this script...
|
|
#
|
|
# Revision 1.118 2005/08/04 16:02:55 tipaul
|
|
# oops... error in synch between 2.2 and head
|
|
#
|
|
# Revision 1.117 2005/08/04 14:24:39 tipaul
|
|
# synch'ing 2.2 and head
|
|
#
|
|
# Revision 1.116 2005/08/04 08:55:54 tipaul
|
|
# Letters / alert system, continuing...
|
|
#
|
|
# * adding a package Letters.pm, that manages Letters & alerts.
|
|
# * adding feature : it's now possible to define a "letter" for any subscription created. If a letter is defined, users in OPAC can put an alert on the subscription. When an issue is marked "arrived", all users in the alert will recieve a mail (as defined in the "letter"). This last part (= send the mail) is not yet developped. (Should be done this week)
|
|
# * adding feature : it's now possible to "put to an alert" in OPAC, for any serial subscription. The alert is stored in a new table, called alert. An alert can be put only if the librarian has activated them in subscription (and they activate it just by choosing a "letter" to sent to borrowers on new issues)
|
|
# * adding feature : librarian can see in borrower detail which alerts they have put, and a user can see in opac-detail which alert they have put too.
|
|
#
|
|
# Note that the system should be generic enough to manage any type of alert.
|
|
# I plan to extend it soon to virtual shelves : a borrower will be able to put an alert on a virtual shelf, to be warned when something is changed in the virtual shelf (mail being sent once a day by cron, or manually by the shelf owner. Anyway, a mail won't be sent on every change, users would be spammed by Koha ;-) )
|
|
#
|
|
# Revision 1.115 2005/08/02 16:15:34 tipaul
|
|
# adding 2 fields to letter system :
|
|
# * module (acquisition, catalogue...) : it will be usefull to show the librarian only letters he may be interested by.
|
|
# * title, that will be used as mail subject.
|
|
#
|
|
# Revision 1.114 2005/07/28 15:10:13 tipaul
|
|
# Introducing new "Letters" system : Letters will be used everytime you want to sent something to someone (through mail or paper). For example, sending a mail for overdues use letter that you can put as parameters. Sending a mail to a borrower when a suggestion is validated uses a letter too.
|
|
# the letter table contains 3 fields :
|
|
# * code => the code of the letter
|
|
# * name => the complete name of the letter
|
|
# * content => the complete text. It's a TEXT field type, so has no limits.
|
|
#
|
|
# My next goal now is to work on point 2-I "serial issue alert"
|
|
# With this feature, in serials, a user can subscribe the "issue alert". For every issue arrived/missing, a mail is sent to all subscribers of this list. The mail warns the user that the issue is arrive or missing. Will be in head.
|
|
# (see mail on koha-devel, 2005/04/07)
|
|
#
|
|
# The "serial issue alert" will be the 1st to use this letter system that probably needs some tweaking ;-)
|
|
#
|
|
# Once it will be stabilised default letters (in any languages) could be added during installer to help the library begin with this new feature.
|
|
#
|
|
# Revision 1.113 2005/07/28 08:38:41 tipaul
|
|
# For instance, the return date does not rely on the borrower expiration date. A systempref will be added in Koha, to modify return date calculation schema :
|
|
# * ReturnBeforeExpiry = yes => return date can't be after expiry date
|
|
# * ReturnBeforeExpiry = no => return date can be after expiry date
|
|
#
|
|
# Revision 1.112 2005/07/26 08:19:47 hdl
|
|
# Adding IndependantBranches System preference variable in order to manage Branch independancy.
|
|
#
|
|
# Revision 1.111 2005/07/25 15:35:38 tipaul
|
|
# we have decided that moving to Koha 3.0 requires being already in Koha 2.2.x
|
|
# So, the updatedatabase script can highly be cleaned (90% removed).
|
|
# Let's play with the new Koha DB structure now ;-)
|
|
#
|