From 098eec4f25dbe04049375dfe77e4bcc12300caaf Mon Sep 17 00:00:00 2001 From: David Cook Date: Thu, 22 Jun 2023 00:56:12 +0000 Subject: [PATCH] Bug 34088: Short circuit database upgrade check If the database version and the code version are the same, we should short circuit and exit immediately. This patch adds the Koha::Installer module which can very quickly check if a db or atomic update is needed. It also moves the logic for C4::Installer::TransformToNum to Koha::Installer::TransformToNum for performance reasons. It also moves the logic for C4::Installer::get_atomic_updates to Koha::Installer::get_atomic_updates for performance reasons. Test plan: 1. Apply patch 2. Run `time koha-upgrade-schema kohadev` 3. Note that it completes in less than .1 seconds 4. To test db updates, change the database Version to a number slightly behind the code version, and run `time koha-upgrade-schema kohadev` 5. Note that the correct version update is processed 6. To test atomic updates: cp installer/data/mysql/atomicupdate/skeleton.pl \ installer/data/mysql/atomicupdate/bug_34088.pl 7. Run `time koha-upgrade-schema kohadev` 8. Note that it takes over 1 second to run and the atomic update is attempted --- C4/Installer.pm | 21 ++----- Koha/Installer.pm | 79 ++++++++++++++++++++++++++ installer/data/mysql/updatedatabase.pl | 7 +++ 3 files changed, 90 insertions(+), 17 deletions(-) create mode 100644 Koha/Installer.pm diff --git a/C4/Installer.pm b/C4/Installer.pm index 9a587cac0f..c839a87d2c 100644 --- a/C4/Installer.pm +++ b/C4/Installer.pm @@ -29,6 +29,7 @@ use DBI; use C4::Context; use Koha::Schema; use Koha; +use Koha::Installer; use vars qw(@ISA @EXPORT); BEGIN { @@ -823,17 +824,8 @@ sub generate_output_db_entry { } sub get_atomic_updates { - my @atomic_upate_files; - # if there is anything in the atomicupdate, read and execute it. - my $update_dir = C4::Context->config('intranetdir') . '/installer/data/mysql/atomicupdate/'; - opendir( my $dirh, $update_dir ); - foreach my $file ( sort readdir $dirh ) { - next if $file !~ /\.(perl|pl)$/; #skip other files - next if $file eq 'skeleton.perl' || $file eq 'skeleton.pl'; # skip the skeleton files - - push @atomic_upate_files, $file; - } - return \@atomic_upate_files; + my $atomic_updates = Koha::Installer::get_atomic_updates(); + return $atomic_updates; } sub run_atomic_updates { @@ -929,12 +921,7 @@ to a number, with just 1 . sub TransformToNum { my $version = shift; - # remove the 3 last . to have a Perl number - $version =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/; - # three X's at the end indicate that you are testing patch with dbrev - # change it into 999 - # prevents error on a < comparison between strings (should be: lt) - $version =~ s/XXX$/999/; + $version = Koha::Installer::TransformToNum($version); return $version; } diff --git a/Koha/Installer.pm b/Koha/Installer.pm new file mode 100644 index 0000000000..ec975e979e --- /dev/null +++ b/Koha/Installer.pm @@ -0,0 +1,79 @@ +package Koha::Installer; + +use Modern::Perl; + +require Koha; +require Koha::Database; +require Koha::Config; + +sub needs_update { + my $needs_update = 1; + my $dbh = Koha::Database::dbh(); + my $sql = "SELECT value FROM systempreferences WHERE variable = 'Version'"; + my $sth = $dbh->prepare($sql); + $sth->execute(); + my $row = $sth->fetchrow_arrayref(); + my $db_version = $row->[0]; + my $koha_version = Koha->version; + my $code_version = TransformToNum($koha_version); + + if ( $db_version == $code_version ) { + $needs_update = 0; + } + + #NOTE: We apply atomic updates even when the DB and code versions align + my $atomic_updates = get_atomic_updates(); + if (@$atomic_updates) { + $needs_update = 1; + } + + return $needs_update; +} + +=head2 TransformToNum + +Transform the Koha version from a 4 parts string +to a number, with just 1 . + +=cut + +sub TransformToNum { + my $version = shift; + + # remove the 3 last . to have a Perl number + $version =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/; + + # three X's at the end indicate that you are testing patch with dbrev + # change it into 999 + # prevents error on a < comparison between strings (should be: lt) + $version =~ s/XXX$/999/; + return $version; +} + +=head2 get_atomic_updates + +Get atomic database updates + +=cut + +sub get_atomic_updates { + my @atomic_upate_files; + + my $conf_fname = Koha::Config->guess_koha_conf; + my $config = Koha::Config->get_instance($conf_fname); + my $intranetdir = $config->{config}->{intranetdir}; + + # if there is anything in the atomicupdate, read and execute it. + my $update_dir = $intranetdir . '/installer/data/mysql/atomicupdate/'; + opendir( my $dirh, $update_dir ); + my @stuff = sort readdir $dirh; + foreach my $file (@stuff) { + next if $file !~ /\.(perl|pl)$/; #skip other files + next if $file eq 'skeleton.perl' || $file eq 'skeleton.pl'; # skip the skeleton files + + push @atomic_upate_files, $file; + } + return \@atomic_upate_files; +} + +1; diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 06f98e8e61..34d9fde66d 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -27,6 +27,13 @@ # NOTE: Please keep the version in kohaversion.pl up-to-date! +BEGIN { + use Koha::Installer; + if ( !Koha::Installer->needs_update ) { + exit; + } +} + use Modern::Perl; use feature 'say'; -- 2.30.2