Bug 10403: (follow-up) fix test to use vendor created earlier during test
[koha.git] / C4 / Installer.pm
index 1dc13aa..2add0e8 100644 (file)
@@ -13,14 +13,16 @@ package C4::Installer;
 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along with
-# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-# Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 use strict;
+#use warnings; FIXME - Bug 2505
 
-our $VERSION = 3.00;
+our $VERSION = 3.07.00.049;
 use C4::Context;
+use C4::Installer::PerlModules;
 
 =head1 NAME
 
@@ -28,35 +30,25 @@ C4::Installer
 
 =head1 SYNOPSIS
 
-use C4::Installer;
-
-my $installer = C4::Installer->new();
-
-my $all_languages = getAllLanguages();
-
-my $error = $installer->load_db_schema();
-
-my $list = $installer->sql_file_list('en', 'marc21', { optional => 1, mandatory => 1 });
-
-my ($fwk_language, $error_list) = $installer->load_sql_in_order($all_languages, @$list);
-
-$installer->set_version_syspref();
-
-$installer->set_marcflavour_syspref('MARC21');
-
-$installer->set_indexing_engine(0);
+ use C4::Installer;
+ my $installer = C4::Installer->new();
+ my $all_languages = getAllLanguages();
+ my $error = $installer->load_db_schema();
+ my $list;
+ #fill $list with list of sql files
+ my ($fwk_language, $error_list) = $installer->load_sql_in_order($all_languages, @$list);
+ $installer->set_version_syspref();
+ $installer->set_marcflavour_syspref('MARC21');
 
 =head1 DESCRIPTION
 
+=cut
+
 =head1 METHODS
 
 =head2 new
 
-=over 4
-
-my $installer = C4::Installer->new();
-
-=back
+  my $installer = C4::Installer->new();
 
 Creates a new installer.
 
@@ -74,48 +66,22 @@ sub new {
     $self->{'port'}     = C4::Context->config("port");
     $self->{'user'}     = C4::Context->config("user");
     $self->{'password'} = C4::Context->config("pass");
-    $self->{'dbh'} = DBI->connect("DBI:$self->{dbms}:dbname=$self->{dbname};host=$self->{hostname}" . 
+    $self->{'dbh'} = DBI->connect("DBI:$self->{dbms}:dbname=$self->{dbname};host=$self->{hostname}" .
                                   ( $self->{port} ? ";port=$self->{port}" : "" ),
                                   $self->{'user'}, $self->{'password'});
     $self->{'language'} = undef;
     $self->{'marcflavour'} = undef;
+       $self->{'dbh'}->do('set NAMES "utf8"');
+    $self->{'dbh'}->{'mysql_enable_utf8'}=1;
 
     bless $self, $class;
     return $self;
 }
 
-=head2 marcflavour_list
-
-=over 4
-
-my ($marcflavours) = $installer->marcflavour_list($lang);
-
-=back
-
-Return a arrayref of the MARC flavour sets available for the
-specified language C<$lang>.  Returns 'undef' if a directory
-for the language does not exist.
-
-=cut
-
-sub marcflavour_list {
-    my $self = shift;
-    my $lang = shift;
-
-    my $dir = C4::Context->config('intranetdir') . "/installer/data/$self->{dbms}/$lang/marcflavour";
-    opendir(MYDIR, $dir) or return;
-    my @list = grep { !/^\.|CVS/ && -d "$dir/$_" } readdir(MYDIR);
-    closedir MYDIR;
-    return \@list;
-}
-
 =head2 marc_framework_sql_list
 
-=over 4
-
-my ($defaulted_to_en, $list) = $installer->marc_framework_sql_list($lang, $marcflavour);
-
-=back
+  my ($defaulted_to_en, $list) = 
+     $installer->marc_framework_sql_list($lang, $marcflavour);
 
 Returns in C<$list> a structure listing the filename, description, section,
 and mandatory/optional status of MARC framework scripts available for C<$lang>
@@ -148,7 +114,7 @@ sub marc_framework_sql_list {
     }
     my @listdir = sort grep { !/^\.|marcflavour/ && -d "$dir/$_" } readdir(MYDIR);
     closedir MYDIR;
-   
+
     my @fwklist;
     my $request = $self->{'dbh'}->prepare("SELECT value FROM systempreferences WHERE variable='FrameworksLoaded'");
     $request->execute;
@@ -167,8 +133,8 @@ sub marc_framework_sql_list {
         my @frameworklist;
         map {
             my $name = substr( $_, 0, -4 );
-            open FILE, "<:utf8","$dir/$requirelevel/$name.txt";
-            my $lines = <FILE>;
+            open my $fh, "<:encoding(UTF-8)", "$dir/$requirelevel/$name.txt";
+            my $lines = <$fh>;
             $lines =~ s/\n|\r/<br \/>/g;
             use utf8;
             utf8::encode($lines) unless ( utf8::is_utf8($lines) );
@@ -190,17 +156,13 @@ sub marc_framework_sql_list {
         $cell{"code"}       = lc($requirelevel);
         push @fwklist, \%cell;
     }
+
     return ($defaulted_to_en, \@fwklist);
 }
 
 =head2 sample_data_sql_list
 
-=over 4
-
-my ($defaulted_to_en, $list) = $installer->sample_data_sql_list($lang);
-
-=back
+  my ($defaulted_to_en, $list) = $installer->sample_data_sql_list($lang);
 
 Returns in C<$list> a structure listing the filename, description, section,
 and mandatory/optional status of sample data scripts available for C<$lang>.
@@ -249,8 +211,8 @@ sub sample_data_sql_list {
         my @frameworklist;
         map {
             my $name = substr( $_, 0, -4 );
-            open FILE, "<:utf8","$dir/$requirelevel/$name.txt";
-            my $lines = <FILE>;
+            open my $fh , "<:encoding(UTF-8)", "$dir/$requirelevel/$name.txt";
+            my $lines = <$fh>;
             $lines =~ s/\n|\r/<br \/>/g;
             use utf8;
             utf8::encode($lines) unless ( utf8::is_utf8($lines) );
@@ -275,52 +237,9 @@ sub sample_data_sql_list {
     return ($defaulted_to_en, \@levellist);
 }
 
-=head2 sql_file_list
-
-=over 4
-
-my $list = $installer->sql_file_list($lang, $marcflavour, $subset_wanted);
+=head2 load_db_schema
 
-=back
-
-Returns an arrayref containing the filepaths of installer SQL scripts
-available for laod.  The C<$lang> and C<$marcflavour> arguments
-specify the desired language and MARC flavour. while C<$subset_wanted>
-is a hashref containing possible named parameters 'mandatory' and 'optional'.
-
-=cut
-
-sub sql_file_list {
-    my $self = shift;
-    my $lang = shift;
-    my $marcflavour = shift;
-    my $subset_wanted = shift;
-
-    my ($marc_defaulted_to_en, $marc_sql) = $self->marc_framework_sql_list($lang, $marcflavour);
-    my ($sample_defaulted_to_en, $sample_sql) = $self->sample_data_sql_list($lang);
-    
-    my @sql_list = ();
-    map { 
-        map {
-            if ($subset_wanted->{'mandatory'}) {
-                push @sql_list, $_->{'fwkfile'} if $_->{'mandatory'};
-            }
-            if ($subset_wanted->{'optional'}) {
-                push @sql_list, $_->{'fwkfile'} unless $_->{'mandatory'};
-            }
-        } @{ $_->{'frameworks'} }
-    } (@$marc_sql, @$sample_sql);
-    
-    return \@sql_list
-}
-
-=head2 load_db_schema 
-
-=over 4
-
-my $error = $installer->load_db_schema();
-
-=back
+  my $error = $installer->load_db_schema();
 
 Loads the SQL script that creates Koha's tables and indexes.  The
 return value is a string containing error messages reported by the
@@ -339,11 +258,7 @@ sub load_db_schema {
 
 =head2 load_sql_in_order
 
-=over 4
-
-my ($fwk_language, $list) = $installer->load_sql_in_order($all_languages, @sql_list);
-
-=back
+  my ($fwk_language, $list) = $installer->load_sql_in_order($all_languages, @sql_list);
 
 Given a list of SQL scripts supplied in C<@sql_list>, loads each of them
 into the database and sets the FrameworksLoaded system preference to names
@@ -354,15 +269,15 @@ directory path).  This means that dependencies among the scripts are to
 be resolved by carefully naming them, keeping in mind that the directory name
 does *not* currently count.
 
-FIXME: this is a rather delicate way of dealing with dependencies between 
-       the install scripts.
+B<FIXME:> this is a rather delicate way of dealing with dependencies between
+the install scripts.
 
 The return value C<$list> is an arrayref containing a hashref for each
 "level" or directory containing SQL scripts; the hashref in turns contains
 a list of hashrefs containing a list of each script load and any error
 messages associated with the loading of each script.
 
-FIXME: The C<$fwk_language> code probably doesn't belong and needs to be
+B<FIXME:> The C<$fwk_language> code probably doesn't belong and needs to be
 moved to a different method.
 
 =cut
@@ -383,6 +298,9 @@ sub load_sql_in_order {
     $request->execute;
     my ($systempreference) = $request->fetchrow;
     $systempreference = '' unless defined $systempreference; # avoid warning
+    # Make sure the global sysprefs.sql file is loaded first
+    my $globalsysprefs = C4::Context->config('intranetdir') . "/installer/data/$self->{dbms}/sysprefs.sql";
+    unshift(@fnames, $globalsysprefs);
     foreach my $file (@fnames) {
         #      warn $file;
         undef $/;
@@ -427,21 +345,17 @@ sub load_sql_in_order {
     return ($fwk_language, \@list);
 }
 
-=head2 set_marcflavour_syspref 
-
-=over 4
-
-$installer->set_marcflavour_syspref($marcflavour);
+=head2 set_marcflavour_syspref
 
-=back
+  $installer->set_marcflavour_syspref($marcflavour);
 
 Set the 'marcflavour' system preference.  The incoming
 C<$marcflavour> references to a subdirectory of
 installer/data/$dbms/$lang/marcflavour, and is
-normalized to MARC21 or UNIMARC.
+normalized to MARC21, UNIMARC or NORMARC.
 
 FIXME: this method assumes that the MARC flavour will be either
-MARC21 or UNIMARC.
+MARC21, UNIMARC or NORMARC.
 
 =cut
 
@@ -453,49 +367,17 @@ sub set_marcflavour_syspref {
     # marc_cleaned finds the marcflavour, without the variant.
     my $marc_cleaned = 'MARC21';
     $marc_cleaned = 'UNIMARC' if $marcflavour =~ /unimarc/i;
+    $marc_cleaned = 'NORMARC' if $marcflavour =~ /normarc/i;
     my $request =
         $self->{'dbh'}->prepare(
-          "INSERT IGNORE INTO `systempreferences` (variable,value,explanation,options,type) VALUES('marcflavour','$marc_cleaned','Define global MARC flavor (MARC21 or UNIMARC) used for character encoding','MARC21|UNIMARC','Choice');"
+          "INSERT IGNORE INTO `systempreferences` (variable,value,explanation,options,type) VALUES('marcflavour','$marc_cleaned','Define global MARC flavor (MARC21, UNIMARC or NORMARC) used for character encoding','MARC21|UNIMARC|NORMARC','Choice');"
         );
     $request->execute;
 }
 
-=head2 set_indexing_engine 
-
-=over 4
-
-$installer->set_indexing_engine($nozebra);
-
-=back
-
-Sets system preferences related to the indexing
-engine.  The C<$nozebra> argument is a boolean;
-if true, turn on NoZebra mode and turn off QueryFuzzy,
-QueryWeightFields, and QueryStemming.  If false, turn
-off NoZebra mode (i.e., use the Zebra search engine).
-
-=cut
-
-sub set_indexing_engine {
-    my $self = shift;
-    my $nozebra = shift;
-
-    if ($nozebra) {
-        $self->{'dbh'}->do("UPDATE systempreferences SET value=1 WHERE variable='NoZebra'");
-        $self->{'dbh'}->do("UPDATE systempreferences SET value=0 WHERE variable in ('QueryFuzzy','QueryWeightFields','QueryStemming')");
-    } else {
-        $self->{'dbh'}->do("UPDATE systempreferences SET value=0 WHERE variable='NoZebra'");
-    }
-
-}
-
 =head2 set_version_syspref
 
-=over 4
-
-$installer->set_version_syspref();
-
-=back
+  $installer->set_version_syspref();
 
 Set or update the 'Version' system preference to the current
 Koha software version.
@@ -517,28 +399,25 @@ sub set_version_syspref {
         my $finish=$self->{'dbh'}->prepare("INSERT 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);
     }
+    C4::Context->clear_syspref_cache();
 }
 
 =head2 load_sql
 
-=over 4
-
-my $error = $installer->load_sql($filename);
-
-=back
+  my $error = $installer->load_sql($filename);
 
 Runs a the specified SQL using the DB's command-line
 SQL tool, and returns any strings sent to STDERR
 by the command-line tool.
 
-FIXME: there has been a long-standing desire to
-       replace this with an SQL loader that goes
-       through DBI; partly for portability issues
-       and partly to improve error handling.
+B<FIXME:> there has been a long-standing desire to
+replace this with an SQL loader that goes
+through DBI; partly for portability issues
+and partly to improve error handling.
 
-FIXME: even using the command-line loader, some more
-       basic error handling should be added - deal
-       with missing files, e.g.
+B<FIXME:> even using the command-line loader, some more
+basic error handling should be added - deal
+with missing files, e.g.
 
 =cut
 
@@ -549,16 +428,25 @@ sub load_sql {
     my $datadir = C4::Context->config('intranetdir') . "/installer/data/$self->{dbms}";
     my $error;
     my $strcmd;
+    my $cmd;
     if ( $self->{dbms} eq 'mysql' ) {
-        $strcmd = "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 <$filename 2>&1 1>/dev/null);
+        $error = qx($strcmd --default-character-set=utf8 <$filename 2>&1 1>/dev/null);
     } elsif ( $self->{dbms} eq 'Pg' ) {
-        $strcmd = "psql "
+        $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} "     : "" )
@@ -566,19 +454,20 @@ sub load_sql {
             . " $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 
+        # so that only true errors are returned to stderr or else the installer will
         # report the import a failure although it really succeded -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";
+    }
     return $error;
 }
 
 =head2 get_file_path_from_name
 
-=over 4
-
-my $filename = $installer->get_file_path_from_name('script_name');
-
-=back
+  my $filename = $installer->get_file_path_from_name('script_name');
 
 searches through the set of known SQL scripts and finds the fully
 qualified path name for the script that mathches the input.
@@ -593,7 +482,7 @@ sub get_file_path_from_name {
     my $partialname = shift;
 
     my $lang = 'en'; # FIXME: how do I know what language I want?
-    
+
     my ($defaulted_to_en, $list) = $self->sample_data_sql_list($lang);
     # warn( Data::Dumper->Dump( [ $list ], [ 'list' ] ) );
 
@@ -620,7 +509,7 @@ sub get_file_path_from_name {
 C4::Installer is a refactoring of logic originally from installer/installer.pl, which was
 originally written by Henri-Damien Laurant.
 
-Koha Developement team <info@koha.org>
+Koha Development Team <http://koha-community.org/>
 
 Galen Charlton <galen.charlton@liblime.com>