From bd684b2007f98d50c37816d7e77056c1d40f2fa2 Mon Sep 17 00:00:00 2001 From: Olli-Antti Kivilahti Date: Mon, 14 Sep 2015 16:29:20 +0300 Subject: [PATCH] Bug 14698 - AtomicUpdater - Followup, add single atomicupdate-script execution. --- Koha/AtomicUpdater.pm | 43 ++++++++++++++++++++++++++---------- installer/data/mysql/atomicupdate.pl | 16 +++++++++++++- t/db_dependent/Koha/AtomicUpdater.t | 33 +++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 13 deletions(-) diff --git a/Koha/AtomicUpdater.pm b/Koha/AtomicUpdater.pm index 919d956..9e6a564 100644 --- a/Koha/AtomicUpdater.pm +++ b/Koha/AtomicUpdater.pm @@ -166,19 +166,8 @@ sub applyAtomicUpdates { my $atomicUpdate = $atomicUpdates->{$issueId}; next unless $atomicUpdate; #Not each ordered Git commit necessarily have a atomicupdate-script. - my $filename = $atomicUpdate->filename; - print "Applying file '$filename'\n" if $self->{verbose} > 2; - - if ( $filename =~ /\.sql$/ ) { - my $installer = C4::Installer->new(); - my $rv = $installer->load_sql( $self->{scriptDir}.'/'.$filename ) ? 0 : 1; - } elsif ( $filename =~ /\.(perl|pl)$/ ) { - do $self->{scriptDir}.'/'.$filename; - } - - $atomicUpdate->store(); + $self->applyAtomicUpdate($atomicUpdate); $appliedUpdates{$issueId} = $atomicUpdate; - print "File '$filename' applied\n" if $self->{verbose} > 2; } #Check that we have actually applied all the updates. @@ -191,6 +180,36 @@ sub applyAtomicUpdates { return \%appliedUpdates; } +sub applyAtomicUpdate { + my ($self, $atomicUpdate) = @_; + #Validate params + unless ($atomicUpdate) { + Koha::Exception::BadParameter->throw(error => __PACKAGE__."->applyAtomicUpdate($atomicUpdate):> Parameter must be a Koha::AtomicUpdate-object or a path to a valid atomicupdates-script!"); + } + if ($atomicUpdate && ref($atomicUpdate) eq '') { #We have a scalar, presumably a filepath to atomicUpdate-script. + $atomicUpdate = Koha::AtomicUpdate->new({filename => $atomicUpdate}); + } + $atomicUpdate = Koha::AtomicUpdater->cast($atomicUpdate); + + my $filename = $atomicUpdate->filename; + print "Applying file '$filename'\n" if $self->{verbose} > 2; + + if ( $filename =~ /\.sql$/ ) { + my $installer = C4::Installer->new(); + my $rv = $installer->load_sql( $self->{scriptDir}.'/'.$filename ) ? 0 : 1; + } elsif ( $filename =~ /\.(perl|pl)$/ ) { + my $fileAndPath = $self->{scriptDir}.'/'.$filename; + unless (my $return = do $fileAndPath ) { + warn "couldn't parse $fileAndPath: $@\n" if $@; + warn "couldn't do $fileAndPath: $!\n" unless defined $return; + warn "couldn't run $fileAndPath\n" unless $return; + } + } + + $atomicUpdate->store(); + print "File '$filename' applied\n" if $self->{verbose} > 2; +} + =head _getValidAtomicUpdateScripts @RETURNS HASHRef of Koha::AtomicUpdate-objects, of all the files diff --git a/installer/data/mysql/atomicupdate.pl b/installer/data/mysql/atomicupdate.pl index a53cf21..051d19e 100644 --- a/installer/data/mysql/atomicupdate.pl +++ b/installer/data/mysql/atomicupdate.pl @@ -34,6 +34,7 @@ my $list = 0; my $pending = 0; my $directory = ''; my $git = ''; +my $single = ''; GetOptions( 'v|verbose:i' => \$verbose, @@ -45,6 +46,7 @@ GetOptions( 'l|list' => \$list, 'p|pending' => \$pending, 'g|git:s' => \$git, + 's|single:s' => \$single, ); my $usage = << 'ENDUSAGE'; @@ -58,21 +60,33 @@ applied. Also acts as a gateway to CRUD the koha.database_updates-table. -v --verbose Integer, 1 is not so verbose, 3 is maximally verbose. + -h --help Flag, This nice help! + -a --apply Flag, Apply all the pending atomicupdates from the atomicupdates-directory. + -d --directory Path, From which directory to look for atomicupdate-scripts. Defaults to '$KOHA_PATH/installer/data/mysql/atomicupdate/' + + -s --single Path, execute a single atomicupdate-script. + eg. atomicupdate/Bug01243-SingleFeature.pl + -r --remove String, Remove the upgrade entry from koha.database_updates eg. --remove "Bug71337" + -i --insert Path, Add an upgrade log entry for the given atomicupdate-file. Useful to revert an accidental --remove -operation or for - testing. + testing. Does not execute the update script, simply adds + the log entry. eg. -i installer/data/mysql/atomicupdate/Bug5453-Example.pl + -l --list Flag, List all entries in the koha.database_updates-table. This typically means all applied atomicupdates. + -p --pending Flag, List all pending atomicupdates from the atomicupdates-directory. + -g --git Path, Build the update order from the Git repository given, or default to the Git repository in $KOHA_PATH. Eg. --git 1, to build with default values, or diff --git a/t/db_dependent/Koha/AtomicUpdater.t b/t/db_dependent/Koha/AtomicUpdater.t index 381f379..974ac0d 100644 --- a/t/db_dependent/Koha/AtomicUpdater.t +++ b/t/db_dependent/Koha/AtomicUpdater.t @@ -270,5 +270,38 @@ sub listPendingAtomicupdates { t::lib::TestObjects::AtomicUpdateFactory->tearDownTestContext($subtestContext); } +subtest "Apply single atomicupdate from file" => \&applySingleAtomicUpdateFromFile; +sub applySingleAtomicUpdateFromFile { + my $subtestContext = {}; + eval { + my $files = t::lib::TestObjects::FileFactory->createTestGroup([ + { filepath => 'atomicupdate/', + filename => 'Bug_01243-SingleUpdate.pl', + content => '$ENV{ATOMICUPDATE_TESTS_2} = 10;',}, + ], + undef, $subtestContext, $testContext); + my $atomicUpdater = Koha::AtomicUpdater->new({ + scriptDir => $files->{'Bug_01243-SingleUpdate.pl'}->dirname() + }); + + $atomicUpdater->applyAtomicUpdate($files->{'Bug_01243-SingleUpdate.pl'}->stringify); + + my $atomicUpdate = $atomicUpdater->find({issue_id => 'Bug01243'}); + t::lib::TestObjects::AtomicUpdateFactory->addToContext($atomicUpdate, undef, $subtestContext, $testContext); #Keep track of changes + + is($atomicUpdate->filename, + "Bug_01243-SingleUpdate.pl", + "Bug_01243-SingleUpdate.pl added to DB"); + is($ENV{ATOMICUPDATE_TESTS_2}, + 10, + "Bug_01243-SingleUpdate.pl executed"); + + }; + if ($@) { + ok(0, $@); + } + t::lib::TestObjects::ObjectFactory->tearDownTestContext($subtestContext); +} + t::lib::TestObjects::ObjectFactory->tearDownTestContext($testContext); done_testing; \ No newline at end of file -- 1.9.1