From 5c151f35aac55c3b4c92fb11397d4ef3b8c9f9b8 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Wed, 18 May 2016 13:23:25 -0300 Subject: [PATCH] Bug 13669: Use perl to load SQL statements from sample data This patch changes C4::Installer::load_sql so it uses File::Slurp [1] to read the SQL files, and SQL::SplitStatement to extract the statements from the full SQL file so they can be passed to $dbh->do. To test: - On Mysql 5.5, run the webinstaller => SUCCESS: Everything works as expected - Apply the patch - Run $ mysql -uroot > DROP DATABASE koha_kohadev ; CREATE DATABASE koha_kohadev; - Run the webinstaller => SUCCESS: Everything works as expected - On Mysql 5.6+ (5.7 is implied) - Run $ mysql -uroot > DROP DATABASE koha_kohadev ; CREATE DATABASE koha_kohadev; - Run the webinstaller => FAIL: It cannot load the sql files due to a password-in-command-line error - Apply the patch - Make sure everything is clean (it should): $ mysql -uroot > DROP DATABASE koha_kohadev ; CREATE DATABASE koha_kohadev; - Run the webinstaller => SUCCESS: EVerything works as expected - Sign off :-D [1] Note: This is a POC patch, in the sense that it does the job, fixes a nasty problem but using File::Slurp to load the SQL files in memory comes with a big runtime penalty. You will notice the install procedure is now much slower, for instance. Signed-off-by: Chris Cormack Signed-off-by: Jonathan Druart Signed-off-by: Kyle M Hall --- C4/Installer.pm | 55 +++++++++++++++---------------------------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/C4/Installer.pm b/C4/Installer.pm index f110477d71..b239853d46 100644 --- a/C4/Installer.pm +++ b/C4/Installer.pm @@ -17,10 +17,11 @@ package C4::Installer; # You should have received a copy of the GNU General Public License # along with Koha; if not, see . -use strict; -#use warnings; FIXME - Bug 2505 +use Modern::Perl; use Encode qw( encode is_utf8 ); +use File::Slurp; +use SQL::SplitStatement; use C4::Context; use C4::Installer::PerlModules; use DBI; @@ -428,46 +429,24 @@ with missing files, e.g. =cut sub load_sql { + my $self = shift; my $filename = shift; - my $datadir = C4::Context->config('intranetdir') . "/installer/data/$self->{dbms}"; - my $error; - my $strcmd; - my $cmd; - if ( $self->{dbms} eq 'mysql' ) { - $cmd = qx(which mysql 2>/dev/null || whereis mysql 2>/dev/null); - chomp $cmd; - $cmd = $1 if ($cmd && $cmd =~ /^(.+?)[\r\n]+$/); - $cmd = 'mysql' if (!$cmd || !-x $cmd); - $strcmd = "$cmd " - . ( $self->{hostname} ? " -h $self->{hostname} " : "" ) - . ( $self->{port} ? " -P $self->{port} " : "" ) - . ( $self->{user} ? " -u $self->{user} " : "" ) - . ( $self->{password} ? " -p'$self->{password}'" : "" ) - . " $self->{dbname} "; - $error = qx($strcmd --default-character-set=utf8 <$filename 2>&1 1>/dev/null); - } elsif ( $self->{dbms} eq 'Pg' ) { - $cmd = qx(which psql 2>/dev/null || whereis psql 2>/dev/null); - chomp $cmd; - $cmd = $1 if ($cmd && $cmd =~ /^(.+?)[\r\n]+$/); - $cmd = 'psql' if (!$cmd || !-x $cmd); - $strcmd = "$cmd " - . ( $self->{hostname} ? " -h $self->{hostname} " : "" ) - . ( $self->{port} ? " -p $self->{port} " : "" ) - . ( $self->{user} ? " -U $self->{user} " : "" ) -# . ( $self->{password} ? " -W $self->{password}" : "" ) # psql will NOT accept a password, but prompts... - . " $self->{dbname} "; # Therefore, be sure to run 'trust' on localhost in pg_hba.conf -fbcit - $error = qx($strcmd -f $filename 2>&1 1>/dev/null); - # Be sure to set 'client_min_messages = error' in postgresql.conf - # so that only true errors are returned to stderr or else the installer will - # report the import as a failure although it really succeeded -fbcit - } -# errors thrown while loading installer data should be logged - if($error) { - warn "C4::Installer::load_sql returned the following errors while attempting to load $filename:\n"; - warn "$error"; + my $dbh = $self->{ dbh }; + + my $sql = read_file( $filename, binmode => ':utf8'); + my $sql_splitter = SQL::SplitStatement->new; + my @statements = $sql_splitter->split($sql); + my $error = ""; + + foreach my $statement ( @statements ) { + $dbh->do($statement); + if( $dbh->err) { + $error .= "$filename (" . $dbh->errstr . "): $statement\n"; + } } + return $error; } -- 2.39.5