Beim Aufruf von check_project() die als nächstes aufzurufende Funktion mitgeben.
[kivitendo-erp.git] / scripts / dbupgrade2_tool.pl
index e688867..f1dcf93 100755 (executable)
@@ -15,6 +15,7 @@ use English '-no_match_vars';
 use DBI;
 use Data::Dumper;
 use Getopt::Long;
+use Text::Iconv;
 
 use SL::LXDebug;
 
@@ -32,20 +33,21 @@ use SL::DBUtils;
 #######
 
 my ($opt_list, $opt_tree, $opt_rtree, $opt_nodeps, $opt_graphviz, $opt_help);
-my ($opt_user, $opt_apply, $opt_applied);
+my ($opt_user, $opt_apply, $opt_applied, $opt_format, $opt_test_utf8);
+my ($opt_dbhost, $opt_dbport, $opt_dbname, $opt_dbuser, $opt_dbpassword);
 
 our (%myconfig, $form, $user, $auth);
 
 sub show_help {
-  my $help_text = <<'END_HELP'
+  my $help_text = <<"END_HELP"
 dbupgrade2_tool.pl [options]
 
   A validation and information tool for the database upgrade scripts
-  in 'sql/Pg-upgrade2'.
+  in \'sql/Pg-upgrade2\'.
 
   At startup dbupgrade2_tool.pl will always check the consistency
   of all database upgrade scripts (e.g. circular references, invalid
-  formats, missing meta information). You can but don't have to specifiy
+  formats, missing meta information). You can but don\'t have to specifiy
   additional actions.
 
   Actions:
@@ -55,23 +57,34 @@ dbupgrade2_tool.pl [options]
     --graphviz[=file]    Create a Postscript document showing a tree of
                          all database upgrades and their dependencies.
                          If no file name is given then the output is
-                         written to 'db_dependencies.ps'.
+                         written to \'db_dependencies.png\'.
+    --format=...         Format for the graphviz output. Defaults to
+                         \'png\'. All values that the command \'dot\' accepts
+                         for it\'s option \'-T\' are acceptable.
     --nodeps             List all database upgrades that no other upgrade
                          depends on
-    --apply=tag          Applies the database upgrades 'tag' and all
-                         upgrades it depends on. If '--apply' is used
-                         then the option '--user' must be used as well.
+    --apply=tag          Applies the database upgrades \'tag\' and all
+                         upgrades it depends on. If \'--apply\' is used
+                         then the option \'--user\' must be used as well.
     --applied            List the applied database upgrades for the
-                         database that the user given with '--user' uses.
+                         database that the user given with \'--user\' uses.
+    --test-utf8          Tests a PostgreSQL cluster for proper UTF-8 support.
+                         You have to specify the database to test with the
+                         parameters --dbname, --dbhost, --dbport, --dbuser
+                         and --dbpassword.
     --help               Show this help and exit.
 
   Options:
     --user=name          The name of the user configuration to use for
                          database connectivity.
-END_HELP
-    ;
+    --dbname=name        Database connection options for the UTF-8
+    --dbhost=host        handling test.
+    --dbport=port
+    --dbuser=user
+    --dbpassword=pw
 
-  # Syntax-Highlighting-Fix für Emacs: '
+END_HELP
+;
 
   print $help_text;
 
@@ -154,14 +167,17 @@ sub dump_tree_reverse {
 }
 
 sub dump_graphviz {
-  my $file_name = shift || "db_dependencies.ps";
+  my %params    = @_;
+
+  my $format    = $params{format}    || "png";
+  my $file_name = $params{file_name} || "db_dependencies.${format}";
 
-  print "GRAPHVIZ POSTCRIPT\n\n";
+  print "GRAPHVIZ OUTPUT -- format: ${format}\n\n";
   print "Output will be written to '${file_name}'\n";
 
   calc_rev_depends();
 
-  $dot = "|dot -Tps ";
+  $dot = "|dot -T${format} ";
   open OUT, "${dot}> \"${file_name}\"" || die;
 
   print OUT
@@ -345,26 +361,34 @@ $locale = Locale->new("de", "login");
 #######
 #######
 
-GetOptions("list"       => \$opt_list,
-           "tree"       => \$opt_tree,
-           "rtree"      => \$opt_rtree,
-           "nodeps"     => \$opt_nodeps,
-           "graphviz:s" => \$opt_graphviz,
-           "user=s"     => \$opt_user,
-           "apply=s"    => \$opt_apply,
-           "applied"    => \$opt_applied,
-           "help"       => \$opt_help,
+GetOptions("list"         => \$opt_list,
+           "tree"         => \$opt_tree,
+           "rtree"        => \$opt_rtree,
+           "nodeps"       => \$opt_nodeps,
+           "graphviz:s"   => \$opt_graphviz,
+           "format:s"     => \$opt_format,
+           "user=s"       => \$opt_user,
+           "apply=s"      => \$opt_apply,
+           "applied"      => \$opt_applied,
+           "test-utf8"    => \$opt_test_utf8,
+           "dbhost:s"     => \$opt_dbhost,
+           "dbport:s"     => \$opt_dbport,
+           "dbname:s"     => \$opt_dbname,
+           "dbuser:s"     => \$opt_dbuser,
+           "dbpassword:s" => \$opt_dbpassword,
+           "help"         => \$opt_help,
   );
 
 show_help() if ($opt_help);
 
 $controls = parse_dbupdate_controls($form, "Pg");
 
-dump_list()                  if ($opt_list);
-dump_tree()                  if ($opt_tree);
-dump_tree_reverse()          if ($opt_rtree);
-dump_graphviz($opt_graphviz) if (defined $opt_graphviz);
-dump_nodeps()                if ($opt_nodeps);
+dump_list()                                 if ($opt_list);
+dump_tree()                                 if ($opt_tree);
+dump_tree_reverse()                         if ($opt_rtree);
+dump_graphviz('file_name' => $opt_graphviz,
+              'format'    => $opt_format)   if (defined $opt_graphviz);
+dump_nodeps()                               if ($opt_nodeps);
 
 if ($opt_user) {
   $auth = SL::Auth->new();
@@ -395,3 +419,35 @@ if ($opt_applied) {
   $form->error("--applied used but no user name given with --user.") if (!$user);
   dump_applied();
 }
+
+if ($opt_test_utf8) {
+  $form->error("--test-utf8 used but no database name given with --dbname.") if (!$opt_dbname);
+
+  my $iconv_to_utf8      = Text::Iconv->new("ISO-8859-15", "UTF-8");
+  my $iconv_from_utf8    = Text::Iconv->new("UTF-8", "ISO-8859-15");
+
+  my $umlaut_upper       = 'Ä';
+  my $umlaut_upper_utf8  = $iconv_to_utf8->convert($umlaut_upper);
+
+  my $dbconnect          = "dbi:Pg:dbname=${opt_dbname}";
+  $dbconnect            .= ";host=${opt_dbhost}" if ($opt_dbhost);
+  $dbconnect            .= ";port=${opt_dbport}" if ($opt_dbport);
+
+  my $dbh                = DBI->connect($dbconnect, $opt_dbuser, $opt_dbpassword);
+
+  $form->error("UTF-8 test: Database connect failed (" . $DBI::errstr . ")") if (!$dbh);
+
+  my ($umlaut_lower_utf8) = $dbh->selectrow_array(qq|SELECT lower(?)|, undef, $umlaut_upper_utf8);
+
+  $dbh->disconnect();
+
+  my $umlaut_lower = $iconv_from_utf8->convert($umlaut_lower_utf8);
+
+  if ($umlaut_lower eq 'ä') {
+    print "UTF-8 test was successful.\n";
+  } elsif ($umlaut_lower eq 'Ä') {
+    print "UTF-8 test was NOT successful: Umlauts are not modified (this might be partially ok, but you should probably not use UTF-8 on this cluster).\n";
+  } else {
+    print "UTF-8 test was NOT successful: Umlauts are destroyed. Do not use UTF-8 on this cluster.\n";
+  }
+}