From 9502b50754afb7059707721092c81ccd4ebe2f23 Mon Sep 17 00:00:00 2001 From: Marcel de Rooy Date: Tue, 14 Oct 2014 11:49:36 +0200 Subject: [PATCH] Bug 13068: Counterpatch using atomicupdate directory Content-Type: text/plain; charset=utf-8 This patch makes a distinction between atomicupdates belonging to an official db revision and development updates. It also keeps track of the dev updates since the last official db rev. (This is done via a local pref; so easily accessible if needed.) The db revs can be txt files, perl scripts or sql files. Sql files are run via the installer. A new db revision is now only a matter of dropping a file in atomicupdates for the developer. The RM only adds one line to updatedatabase like: ExecDBRev( $aupd, '13068', 'Refined dbrev', '13068.pl', '3.17.00.028'); This line should follow the last dbrev and preceed the call to RunRemainingAtomicUpdates. Test plan: [1] Add a few lines calling ExecDBRev to updatedatabase with corresponding files in atomicupdate like (insert the correct version!!): ExecDBRev( $aupd, '13068', 'My test', '13068.pl', '3.17.00.028'); Do not forget to update kohaversion.pl accordingly. Add some other files in atomicupdate as dev updates. [2] Run updatestructure and check if all db revs and dev updates are run. Run updatestructure again. Nothing should be run now. Clear/delete the _LocalAtomicUpdates pref. Run updatestructure again. Only dev updates should be run. Reset the database version. You could edit Version in local preferences. Run updatestructure and check if all db revs and dev updates are run. Edit _LocalAtomicUpdates and remove one filename. Run updatestructure again. Only one dev update should be run. Signed-off-by: Marcel de Rooy --- installer/data/mysql/updatedatabase.pl | 100 ++++++++++++++++++++++++++++++++ 1 files changed, 100 insertions(+), 0 deletions(-) diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 57464ba..6df583d 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -38,13 +38,24 @@ use C4::Context; use C4::Installer; use C4::Dates; +use File::Slurp; use MARC::Record; use MARC::File::XML ( BinaryEncoding => 'utf8' ); +use constant ATOMICUPD_PREF => '_LocalAtomicUpdates'; + # FIXME - The user might be installing a new database, so can't rely # on /etc/koha.conf anyway. my $debug = 0; +my $aupd = { #hash for atomic updates + location => C4::Context->config('intranetdir')."/installer/data/mysql/atomicupdate", + remember => C4::Context->preference(ATOMICUPD_PREF)//'', + skipfiles => { + 'Bug-4246-Talking-Tech-itiva-phone-notifications.pl' => 1, + 'oai_sets.sql' => 1, + }, +}; my ( $sth, $sti, @@ -8869,6 +8880,94 @@ if ( CheckVersion($DBversion) ) { =head1 FUNCTIONS +=head2 RunRemainingAtomicUpdates + +This subroutine will run all development updates in the atomicupdate +directory. It will skip the official db revisions, that have been +collected in the skipfiles hash. It also skips recently applied +dev updates as recorded in local pref _LocalAtomicUpdates. + +=cut + +sub RunRemainingAtomicUpdates { + my ( $atomicupd ) = @_; + my $loc = $atomicupd->{location}; + my @updates = glob( $loc .'/*'); + foreach my $upd ( sort @updates ) { #sort feels safer here + $upd =~ s/$loc\///; + if( exists $atomicupd->{skipfiles}->{$upd} ) { + next; # Skip official db revision + } + if( $atomicupd->{remember} =~ /(^|;)$upd;/ ) { + #Skip files that have recently been applied + #Note that an official db rev erases this list + print "Skipping $upd as recently applied dev update\n"; + next; + } + if( $upd !~ /\.(txt|sql|pl)$/ ) { + print "Unsupported file format: $upd\n"; + next; + } + ExecDBRev( $atomicupd, '', '', $upd, 'XXX' ); + } +} + +=head2 ExecDBRev + +This subroutine checks if an official db revision should still be +applied. If not, it records the file in the skipfiles hash and returns. +Otherwise it applies the db rev from the atomicupdate directory. +The db rev can be a perl file, a sql file or a txt file. + +=cut + +sub ExecDBRev { + my ( $atomicupd, $bugno, $descr, $file, $version ) = @_; + + my $devrun = $version=~/XXX$/; + $atomicupd->{skipfiles}->{$file} = 1 if !$devrun && $file; + return 0 if !CheckVersion($version); + + my $rv; + if( $file =~ /\.txt$/ ) { + #This dbrev prints some warning + my $contents= read_file( $atomicupd->{location}. "/$file" ); + print $contents; + $rv = 1; + } elsif( $file =~ /\.pl$/ ) { + #Run perl script + $rv = do $atomicupd->{location}. "/$file"; + if( !$rv ) { + print "ERROR: $@\n" if $@; + print "ERROR: $!\n" if $!; + $rv = 1 if !$! && !$@; #apparently, the file does not end with 1; + } + } elsif( $file =~ /\.sql$/ ) { + #Run sql file via installer + my $installer = C4::Installer->new(); + $rv = $installer->load_sql( $atomicupd->{location}. "/$file" )? 0: 1; + #Note: load_sql already warns + } else { + print "DB rev $version contains unsupported file $file\n"; + $rv = 0; + } + + if( $devrun ) { + print "Dev upgrade $file done\n"; + _atomic_memory( $atomicupd, $file ) if $rv; + } else { + _atomic_memory( $atomicupd ); #Official db rev clears the atomic pref + SetVersion($version); + print "Upgrade to $version done (Bug $bugno - $descr)\n"; + } +} + +sub _atomic_memory { + my ( $atomicupd, $upd ) = @_; + $atomicupd->{remember}= $upd? $atomicupd->{remember}."$upd;": ''; + C4::Context->set_preference( ATOMICUPD_PREF, $atomicupd->{remember} ); +} + =head2 TableExists($table) =cut @@ -8978,4 +9077,5 @@ sub CheckVersion { } } +RunRemainingAtomicUpdates( $aupd ); exit; -- 1.7.7.6