From 9ec159c2b7db838ef75770ce8604c9321898eccc Mon Sep 17 00:00:00 2001
From: Jonathan Druart <jonathan.druart@biblibre.com>
Date: Fri, 6 Jul 2012 11:57:47 +0200
Subject: [PATCH] Bug 7167: Improve the update.pl script

 * Added CLI options to update.pl
 * Call update.pl from the installer.

Signed-off-by: Paul Poulain <paul.poulain@biblibre.com>
---
 C4/Update/Database.pm          |   22 +++++++++------
 installer/data/mysql/update.pl |   61 ++++++++++++++++++++++++++++++++++++++--
 installer/install.pl           |   38 +++++++++++++++++--------
 3 files changed, 98 insertions(+), 23 deletions(-)

diff --git a/C4/Update/Database.pm b/C4/Update/Database.pm
index 4e41694..f43bd44 100644
--- a/C4/Update/Database.pm
+++ b/C4/Update/Database.pm
@@ -431,7 +431,7 @@ sub md5_already_exists {
 =cut
 sub set_infos {
     my ( $version, $queries, $errors, $md5 ) = @_;
-    #SetVersion($DBversion) if not -s $errors;
+    SetVersion($version) if not -s $errors;
     for my $query ( @{ $queries->{queries} } ) {
         my $sth = $dbh->prepare("INSERT INTO updatedb_query(version, query) VALUES (?, ?)");
         $sth->execute( $version, $query );
@@ -516,15 +516,19 @@ sub TransformToNum {
 }
 
 sub SetVersion {
-    my $kohaversion = TransformToNum(shift);
-    if ( C4::Context->preference('Version') ) {
+    my $new_version = TransformToNum(shift);
+    my $current_version = TransformToNum( C4::Context->preference('Version') );
+    unless ( C4::Context->preference('Version') ) {
+        my $finish = $dbh->prepare(qq{
+            INSERT IGNORE INTO systempreferences (variable,value,explanation)
+            VALUES ('Version',?,'The Koha database version. WARNING: Do not change this value manually, it is maintained by the webinstaller')
+        });
+        $finish->execute($new_version);
+        return;
+    }
+    if ( $new_version > $current_version ) {
         my $finish = $dbh->prepare("UPDATE systempreferences SET value=? WHERE variable='Version'");
-        $finish->execute($kohaversion);
-    } else {
-        my $finish = $dbh->prepare(
-"INSERT IGNORE INTO systempreferences (variable,value,explanation) values ('Version',?,'The Koha database version. WARNING: Do not change this value manually, it is maintained by the webinstaller')"
-        );
-        $finish->execute($kohaversion);
+        $finish->execute($new_version);
     }
 }
 
diff --git a/installer/data/mysql/update.pl b/installer/data/mysql/update.pl
index 92275c7..e8dac36 100644
--- a/installer/data/mysql/update.pl
+++ b/installer/data/mysql/update.pl
@@ -4,17 +4,29 @@ use C4::Context;
 use C4::Update::Database;
 use Getopt::Long;
 
-
+my $help;
 my $version;
 my $list;
+my $all;
+my $min;
 
 GetOptions(
-    'm:s' => \$version,
-    'l'   => \$list,
+    'h|help|?'     => \$help,
+    'm:s'   => \$version,
+    'l|list'     => \$list,
+    'a|all'   => \$all,
+    'min:s' => \$min,
 );
 
+if ( $help or not ($version or $list or $all) ) {
+    usage();
+    exit;
+}
+
+my @reports;
 if ( $version ) {
     my $report = C4::Update::Database::execute_version($version);
+    push @reports, $report;
 }
 
 if ( $list ) {
@@ -26,3 +38,46 @@ if ( $list ) {
     say "\t- $$_{version}" for @$versions;
 
 }
+
+if ( $all ) {
+    my $versions_availables = C4::Update::Database::list_versions_availables();
+    my $versions = C4::Update::Database::list_versions_already_knows;
+    my $min_version = $min
+        ? $min =~ m/\d\.\d{2}\.\d{2}\.\d{3}/
+            ? C4::Update::Database::TransformToNum( $min )
+            : $min
+        : 0;
+
+    for my $v ( @$versions_availables ) {
+        if ( not grep { $v eq $$_{version} } @$versions
+             and C4::Update::Database::TransformToNum( $v ) >= $min_version
+        ) {
+            my $report = C4::Update::Database::execute_version $v;
+            push @reports, $report;
+        }
+    }
+}
+
+if ( $version or $all ) {
+    say "Report:";
+    for my $report ( @reports ) {
+        my ( $v, $r ) = each %$report;
+        if ( ref( $r ) eq 'HASH' ) {
+            say "\t$v => $r->{error}";
+        } else {
+            say "\t$v => $r";
+        }
+    }
+}
+
+sub usage {
+    say "update.pl";
+    say "This script updates your database for you";
+    say "Usage:";
+    say "\t-h\tShow this help message";
+    say "\t-m\tExecute a given version";
+    say "\t-l\tList all the versions";
+    say "\t-all\tExecute all available versions";
+    say "\t-min\tWith -all, Execute all available versions since a given version";
+    say "\t\tCan be X.XX.XX.XXX or X.XXXXXXX";
+}
diff --git a/installer/install.pl b/installer/install.pl
index d9feac4..7a6849a 100755
--- a/installer/install.pl
+++ b/installer/install.pl
@@ -321,19 +321,19 @@ elsif ( $step && $step == 3 ) {
         warn "# plack? inserted PERL5LIB $ENV{PERL5LIB}\n";
     }
 
-        my $cmd = C4::Context->config("intranetdir") . "/installer/data/$info{dbms}/updatedatabase.pl";
-        my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) = IPC::Cmd::run(command => $cmd, verbose => 0);
+        my $koha39 =~ "3.0900000";
+        my $cmd;
+        # Old updatedatabase method
+        my $current_version = C4::Context->preference('Version');
+        if ( $current_version < $koha39 ) {
+            $cmd = C4::Context->config("intranetdir") . "/installer/data/$info{dbms}/updatedatabase.pl";
+            my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) = IPC::Cmd::run(command => $cmd, verbose => 0);
+            print_std( "updatedatabase.pl", $stdout_buf, $stderr_buf );
 
-        if (@$stdout_buf) {
-            $template->param(update_report => [ map { { line => $_ } } split(/\n/, join('', @$stdout_buf)) ] );
-            $template->param(has_update_succeeds => 1);
-        }
-        if (@$stderr_buf) {
-            $template->param(update_errors => [ map { { line => $_ } } split(/\n/, join('', @$stderr_buf)) ] );
-            $template->param(has_update_errors => 1);
-            warn "The following errors were returned while attempting to run the updatedatabase.pl script:\n";
-            foreach my $line (@$stderr_buf) {warn "$line\n";}
         }
+        $cmd = C4::Context->config("intranetdir") . "/installer/data/$info{dbms}/update.pl -all -min=$current_version";
+        my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) = IPC::Cmd::run(command => $cmd, verbose => 0);
+        print_std( "update.pl", $stdout_buf, $stderr_buf );
 
         $template->param( $op => 1 );
     }
@@ -406,4 +406,20 @@ else {
         }
     }
 }
+
+sub print_std {
+    my ( $script, $stdout_buf, $stderr_buf ) = @_;
+    if (@$stdout_buf) {
+        $template->param(update_report => [ map { { line => $_ } } split(/\n/, join('', @$stdout_buf)) ] );
+        $template->param(has_update_succeeds => 1);
+    }
+    if (@$stderr_buf) {
+        $template->param(update_errors => [ map { { line => $_ } } split(/\n/, join('', @$stderr_buf)) ] );
+        $template->param(has_update_errors => 1);
+        warn "The following errors were returned while attempting to run the $script script:\n";
+        foreach my $line (@$stderr_buf) {warn "$line\n";}
+    }
+}
+
+
 output_html_with_http_headers $query, $cookie, $template->output;
-- 
1.7.9.5