1 #=====================================================================
 
   4 # Based on SQL-Ledger Version 2.1.9
 
   5 # Web http://www.lx-office.org
 
   7 #=====================================================================
 
   8 # SQL-Ledger Accounting
 
  11 #  Author: Dieter Simader
 
  12 #   Email: dsimader@sql-ledger.org
 
  13 #     Web: http://www.sql-ledger.org
 
  17 # This program is free software; you can redistribute it and/or modify
 
  18 # it under the terms of the GNU General Public License as published by
 
  19 # the Free Software Foundation; either version 2 of the License, or
 
  20 # (at your option) any later version.
 
  22 # This program is distributed in the hope that it will be useful,
 
  23 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  24 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  25 # GNU General Public License for more details.
 
  26 # You should have received a copy of the GNU General Public License
 
  27 # along with this program; if not, write to the Free Software
 
  28 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
  29 #=====================================================================
 
  31 # user related functions
 
  33 #=====================================================================
 
  47   $main::lxdebug->enter_sub();
 
  49   my ($type, $login) = @_;
 
  54     my %user_data = $main::auth->read_user($login);
 
  55     map { $self->{$_} = $user_data{$_} } keys %user_data;
 
  58   $main::lxdebug->leave_sub();
 
  64   $main::lxdebug->enter_sub();
 
  71   # scan the locale directory and read in the LANGUAGE files
 
  72   opendir(DIR, "locale");
 
  74   my @dir = grep(!/(^\.\.?$|\..*)/, readdir(DIR));
 
  76   foreach my $dir (@dir) {
 
  77     next unless open(FH, "locale/$dir/LANGUAGE");
 
  81     $cc{$dir} = "@language";
 
  86   $main::lxdebug->leave_sub();
 
  92   $main::lxdebug->enter_sub();
 
  94   my ($self, $form) = @_;
 
 100   if ($self->{login}) {
 
 101     my %myconfig = $main::auth->read_user($self->{login});
 
 103     # check if database is down
 
 105       DBI->connect($myconfig{dbconnect}, $myconfig{dbuser},
 
 107       or $self->error(DBI::errstr);
 
 109     # we got a connection, check the version
 
 110     my $query = qq|SELECT version FROM defaults|;
 
 111     my $sth   = $dbh->prepare($query);
 
 112     $sth->execute || $form->dberror($query);
 
 114     my ($dbversion) = $sth->fetchrow_array;
 
 117     $self->create_employee_entry($form, $dbh, \%myconfig);
 
 119     $self->create_schema_info_table($form, $dbh);
 
 126       parse_dbupdate_controls($form, $myconfig{"dbdriver"});
 
 128     map({ $form->{$_} = $myconfig{$_} }
 
 129         qw(dbname dbhost dbport dbdriver dbuser dbpasswd dbconnect dateformat));
 
 131     if (update_available($myconfig{"dbdriver"}, $dbversion) ||
 
 132         update2_available($form, $controls)) {
 
 134       $form->{"stylesheet"} = "lx-office-erp.css";
 
 135       $form->{"title"} = $main::locale->text("Dataset upgrade");
 
 137       print $form->parse_html_template("dbupgrade/header");
 
 139       $form->{dbupdate} = "db$myconfig{dbname}";
 
 140       $form->{ $form->{dbupdate} } = 1;
 
 142       if ($form->{"show_dbupdate_warning"}) {
 
 143         print $form->parse_html_template("dbupgrade/warning");
 
 148       open(FH, ">$main::userspath/nologin") or die("$!");
 
 150       # required for Oracle
 
 151       $form->{dbdefault} = $sid;
 
 153       # ignore HUP, QUIT in case the webserver times out
 
 154       $SIG{HUP}  = 'IGNORE';
 
 155       $SIG{QUIT} = 'IGNORE';
 
 157       $self->dbupdate($form);
 
 158       $self->dbupdate2($form, $controls);
 
 163       unlink("$main::userspath/nologin");
 
 166         $self->{"menustyle"} eq "v3" ? "menuv3.pl" :
 
 167         $self->{"menustyle"} eq "neu" ? "menunew.pl" :
 
 168         $self->{"menustyle"} eq "xml" ? "menuXML.pl" :
 
 171       print $form->parse_html_template("dbupgrade/footer", { "menufile" => $menufile });
 
 178   $main::lxdebug->leave_sub();
 
 184   $main::lxdebug->enter_sub();
 
 186   my ($form, $db) = @_;
 
 189         'Pg' => { 'yy-mm-dd'   => 'set DateStyle to \'ISO\'',
 
 190                   'yyyy-mm-dd' => 'set DateStyle to \'ISO\'',
 
 191                   'mm/dd/yy'   => 'set DateStyle to \'SQL, US\'',
 
 192                   'mm-dd-yy'   => 'set DateStyle to \'POSTGRES, US\'',
 
 193                   'dd/mm/yy'   => 'set DateStyle to \'SQL, EUROPEAN\'',
 
 194                   'dd-mm-yy'   => 'set DateStyle to \'POSTGRES, EUROPEAN\'',
 
 195                   'dd.mm.yy'   => 'set DateStyle to \'GERMAN\''
 
 198           'yy-mm-dd'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'YY-MM-DD\'',
 
 199           'yyyy-mm-dd' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'YYYY-MM-DD\'',
 
 200           'mm/dd/yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'MM/DD/YY\'',
 
 201           'mm-dd-yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'MM-DD-YY\'',
 
 202           'dd/mm/yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD/MM/YY\'',
 
 203           'dd-mm-yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD-MM-YY\'',
 
 204           'dd.mm.yy'   => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD.MM.YY\'',
 
 207   $form->{dboptions} = $dboptions{ $form->{dbdriver} }{ $form->{dateformat} };
 
 209   if ($form->{dbdriver} eq 'Pg') {
 
 210     $form->{dbconnect} = "dbi:Pg:dbname=$db";
 
 213   if ($form->{dbdriver} eq 'Oracle') {
 
 214     $form->{dbconnect} = "dbi:Oracle:sid=$form->{sid}";
 
 217   if ($form->{dbhost}) {
 
 218     $form->{dbconnect} .= ";host=$form->{dbhost}";
 
 220   if ($form->{dbport}) {
 
 221     $form->{dbconnect} .= ";port=$form->{dbport}";
 
 224   $main::lxdebug->leave_sub();
 
 228   $main::lxdebug->enter_sub();
 
 230   my @drivers = DBI->available_drivers();
 
 232   $main::lxdebug->leave_sub();
 
 234   return (grep { /(Pg|Oracle)/ } @drivers);
 
 238   $main::lxdebug->enter_sub();
 
 240   my ($self, $form) = @_;
 
 245   $form->{dbdefault} = $form->{dbuser} unless $form->{dbdefault};
 
 246   $form->{sid} = $form->{dbdefault};
 
 247   &dbconnect_vars($form, $form->{dbdefault});
 
 250     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 253   if ($form->{dbdriver} eq 'Pg') {
 
 255       qq|SELECT datname FROM pg_database | .
 
 256       qq|WHERE NOT datname IN ('template0', 'template1')|;
 
 257     $sth = $dbh->prepare($query);
 
 258     $sth->execute() || $form->dberror($query);
 
 260     while (my ($db) = $sth->fetchrow_array) {
 
 262       if ($form->{only_acc_db}) {
 
 264         next if ($db =~ /^template/);
 
 266         &dbconnect_vars($form, $db);
 
 268           DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 272           qq|SELECT tablename FROM pg_tables | .
 
 273           qq|WHERE (tablename = 'defaults') AND (tableowner = ?)|;
 
 274         my $sth = $dbh->prepare($query);
 
 275         $sth->execute($form->{dbuser}) ||
 
 276           $form->dberror($query . " ($form->{dbuser})");
 
 278         if ($sth->fetchrow_array) {
 
 279           push(@dbsources, $db);
 
 285       push(@dbsources, $db);
 
 289   if ($form->{dbdriver} eq 'Oracle') {
 
 290     if ($form->{only_acc_db}) {
 
 292         qq|SELECT owner FROM dba_objects | .
 
 293         qq|WHERE object_name = 'DEFAULTS' AND object_type = 'TABLE'|;
 
 295       $query = qq|SELECT username FROM dba_users|;
 
 298     $sth = $dbh->prepare($query);
 
 299     $sth->execute || $form->dberror($query);
 
 301     while (my ($db) = $sth->fetchrow_array) {
 
 302       push(@dbsources, $db);
 
 309   $main::lxdebug->leave_sub();
 
 315   $main::lxdebug->enter_sub();
 
 317   my ($self, $form) = @_;
 
 319   $form->{sid} = $form->{dbdefault};
 
 320   &dbconnect_vars($form, $form->{dbdefault});
 
 322     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 324   $form->{db} =~ s/\"//g;
 
 326     'Pg'     => qq|CREATE DATABASE "$form->{db}"|,
 
 328     qq|CREATE USER "$form->{db}" DEFAULT TABLESPACE USERS | .
 
 329     qq|TEMPORARY TABLESPACE TEMP IDENTIFIED BY "$form->{db}"|
 
 336   push(@{$dboptions{"Pg"}}, "ENCODING = " . $dbh->quote($form->{"encoding"}))
 
 337     if ($form->{"encoding"});
 
 338   if ($form->{"dbdefault"}) {
 
 339     my $dbdefault = $form->{"dbdefault"};
 
 340     $dbdefault =~ s/[^a-zA-Z0-9_\-]//g;
 
 341     push(@{$dboptions{"Pg"}}, "TEMPLATE = $dbdefault");
 
 344   my $query = $dbcreate{$form->{dbdriver}};
 
 345   $query .= " WITH " . join(" ", @{$dboptions{"Pg"}}) if (@{$dboptions{"Pg"}});
 
 347   # Ignore errors if the database exists.
 
 350   if ($form->{dbdriver} eq 'Oracle') {
 
 351     $query = qq|GRANT CONNECT, RESOURCE TO "$form->{db}"|;
 
 352     do_query($form, $dbh, $query);
 
 356   # setup variables for the new database
 
 357   if ($form->{dbdriver} eq 'Oracle') {
 
 358     $form->{dbuser}   = $form->{db};
 
 359     $form->{dbpasswd} = $form->{db};
 
 362   &dbconnect_vars($form, $form->{db});
 
 364   $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 367   my $db_charset = $Common::db_encoding_to_charset{$form->{encoding}};
 
 368   $db_charset ||= Common::DEFAULT_CHARSET;
 
 371   $self->process_query($form, $dbh, "sql/lx-office.sql", undef, $db_charset);
 
 373   # load chart of accounts
 
 374   $self->process_query($form, $dbh, "sql/$form->{chart}-chart.sql", undef, $db_charset);
 
 376   $query = "UPDATE defaults SET coa = ?";
 
 377   do_query($form, $dbh, $query, $form->{chart});
 
 381   $main::lxdebug->leave_sub();
 
 384 # Process a Perl script which updates the database.
 
 385 # If the script returns 1 then the update was successful.
 
 386 # Return code "2" means "needs more interaction; remove
 
 387 # users/nologin and exit".
 
 388 # All other return codes are fatal errors.
 
 389 sub process_perl_script {
 
 390   $main::lxdebug->enter_sub();
 
 392   my ($self, $form, $dbh, $filename, $version_or_control, $db_charset) = @_;
 
 394   my $fh = IO::File->new($filename, "r") or $form->error("$filename : $!\n");
 
 396   my $file_charset = Common::DEFAULT_CHARSET;
 
 398   if (ref($version_or_control) eq "HASH") {
 
 399     $file_charset = $version_or_control->{charset};
 
 404       next if !/^--\s*\@charset:\s*(.+)/;
 
 408     $fh->seek(0, SEEK_SET);
 
 411   my $contents = join "", <$fh>;
 
 414   $db_charset ||= Common::DEFAULT_CHARSET;
 
 416   my $iconv = SL::Iconv::get_converter($file_charset, $db_charset);
 
 420   my %dbup_myconfig = ();
 
 421   map({ $dbup_myconfig{$_} = $form->{$_}; }
 
 422       qw(dbname dbuser dbpasswd dbhost dbport dbconnect));
 
 424   my $nls_file = $filename;
 
 425   $nls_file =~ s|.*/||;
 
 426   $nls_file =~ s|.pl$||;
 
 427   my $dbup_locale = Locale->new($main::language, $nls_file);
 
 429   my $result = eval($contents);
 
 436   if (!defined($result)) {
 
 437     print $form->parse_html_template("dbupgrade/error",
 
 438                                      { "file"  => $filename,
 
 441   } elsif (1 != $result) {
 
 442     unlink("users/nologin") if (2 == $result);
 
 446   if (ref($version_or_control) eq "HASH") {
 
 447     $dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
 
 448              $dbh->quote($version_or_control->{"tag"}) . ", " .
 
 449              $dbh->quote($form->{"login"}) . ")");
 
 450   } elsif ($version_or_control) {
 
 451     $dbh->do("UPDATE defaults SET version = " .
 
 452              $dbh->quote($version_or_control));
 
 456   $main::lxdebug->leave_sub();
 
 460   $main::lxdebug->enter_sub();
 
 462   my ($self, $form, $dbh, $filename, $version_or_control, $db_charset) = @_;
 
 464   my $fh = IO::File->new($filename, "r") or $form->error("$filename : $!\n");
 
 469   my $file_charset = Common::DEFAULT_CHARSET;
 
 472     next if !/^--\s*\@charset:\s*(.+)/;
 
 476   $fh->seek(0, SEEK_SET);
 
 478   $db_charset ||= Common::DEFAULT_CHARSET;
 
 483     $_ = SL::Iconv::convert($file_charset, $db_charset, $_);
 
 485     # Remove DOS and Unix style line endings.
 
 491     for (my $i = 0; $i < length($_); $i++) {
 
 492       my $char = substr($_, $i, 1);
 
 494       # Are we inside a string?
 
 496         if ($char eq $quote_chars[-1]) {
 
 502         if (($char eq "'") || ($char eq "\"")) {
 
 503           push(@quote_chars, $char);
 
 505         } elsif ($char eq ";") {
 
 507           # Query is complete. Send it.
 
 509           $sth = $dbh->prepare($query);
 
 510           if (!$sth->execute()) {
 
 511             my $errstr = $dbh->errstr;
 
 514             $form->dberror("The database update/creation did not succeed. " .
 
 515                            "The file ${filename} containing the following " .
 
 516                            "query failed:<br>${query}<br>" .
 
 517                            "The error message was: ${errstr}<br>" .
 
 518                            "All changes in that file have been reverted.");
 
 531   if (ref($version_or_control) eq "HASH") {
 
 532     $dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
 
 533              $dbh->quote($version_or_control->{"tag"}) . ", " .
 
 534              $dbh->quote($form->{"login"}) . ")");
 
 535   } elsif ($version_or_control) {
 
 536     $dbh->do("UPDATE defaults SET version = " .
 
 537              $dbh->quote($version_or_control));
 
 543   $main::lxdebug->leave_sub();
 
 547   $main::lxdebug->enter_sub();
 
 549   my ($self, $form) = @_;
 
 550   $form->{db} =~ s/\"//g;
 
 551   my %dbdelete = ('Pg'     => qq|DROP DATABASE "$form->{db}"|,
 
 552                   'Oracle' => qq|DROP USER "$form->{db}" CASCADE|);
 
 554   $form->{sid} = $form->{dbdefault};
 
 555   &dbconnect_vars($form, $form->{dbdefault});
 
 557     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 559   my $query = $dbdelete{$form->{dbdriver}};
 
 560   do_query($form, $dbh, $query);
 
 564   $main::lxdebug->leave_sub();
 
 567 sub dbsources_unused {
 
 568   $main::lxdebug->enter_sub();
 
 570   my ($self, $form) = @_;
 
 572   $form->{only_acc_db} = 1;
 
 574   my %members = $main::auth->read_all_users();
 
 575   my %dbexcl  = map { $_ => 1 } grep { $_ } map { $_->{dbname} } values %members;
 
 577   $dbexcl{$form->{dbdefault}}             = 1;
 
 578   $dbexcl{$main::auth->{DB_config}->{db}} = 1;
 
 580   my @dbunused = grep { !$dbexcl{$_} } dbsources("", $form);
 
 582   $main::lxdebug->leave_sub();
 
 588   $main::lxdebug->enter_sub();
 
 590   my ($self, $form) = @_;
 
 592   my %members  = $main::auth->read_all_users();
 
 593   my $controls = parse_dbupdate_controls($form, $form->{dbdriver});
 
 595   my ($query, $sth, %dbs_needing_updates);
 
 597   foreach my $login (grep /[a-z]/, keys %members) {
 
 598     my $member = $members{$login};
 
 600     map { $form->{$_} = $member->{$_} } qw(dbname dbuser dbpasswd dbhost dbport);
 
 601     dbconnect_vars($form, $form->{dbname});
 
 603     my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd});
 
 609     $query = qq|SELECT version FROM defaults|;
 
 610     $sth = prepare_query($form, $dbh, $query);
 
 611     if ($sth->execute()) {
 
 612       ($version) = $sth->fetchrow_array();
 
 617     next unless $version;
 
 619     if (update_available($form->{dbdriver}, $version) || update2_available($form, $controls)) {
 
 621       map { $dbinfo->{$_} = $member->{$_} } grep /^db/, keys %{ $member };
 
 622       $dbs_needing_updates{$member->{dbhost} . "::" . $member->{dbname}} = $dbinfo;
 
 626   $main::lxdebug->leave_sub();
 
 628   return values %dbs_needing_updates;
 
 632   $main::lxdebug->enter_sub(2);
 
 634   my (@v, $version, $i);
 
 636   @v = split(/\./, $_[0]);
 
 637   while (scalar(@v) < 4) {
 
 641   for ($i = 0; $i < 4; $i++) {
 
 646   $main::lxdebug->leave_sub(2);
 
 650 sub cmp_script_version {
 
 651   my ($a_from, $a_to, $b_from, $b_to);
 
 652   my ($i, $res_a, $res_b);
 
 653   my ($my_a, $my_b) = ($a, $b);
 
 655   $my_a =~ s/.*-upgrade-//;
 
 657   $my_b =~ s/.*-upgrade-//;
 
 659   ($my_a_from, $my_a_to) = split(/-/, $my_a);
 
 660   ($my_b_from, $my_b_to) = split(/-/, $my_b);
 
 662   $res_a = calc_version($my_a_from);
 
 663   $res_b = calc_version($my_b_from);
 
 665   if ($res_a == $res_b) {
 
 666     $res_a = calc_version($my_a_to);
 
 667     $res_b = calc_version($my_b_to);
 
 670   return $res_a <=> $res_b;
 
 673 sub update_available {
 
 674   my ($dbdriver, $cur_version) = @_;
 
 678   opendir SQLDIR, "sql/${dbdriver}-upgrade" || error("", "sql/${dbdriver}-upgrade: $!");
 
 679   my @upgradescripts = grep /${dbdriver}-upgrade-\Q$cur_version\E.*\.(sql|pl)$/, readdir SQLDIR;
 
 682   return ($#upgradescripts > -1);
 
 685 sub create_schema_info_table {
 
 686   $main::lxdebug->enter_sub();
 
 688   my ($self, $form, $dbh) = @_;
 
 690   my $query = "SELECT tag FROM schema_info LIMIT 1";
 
 691   if (!$dbh->do($query)) {
 
 694       qq|CREATE TABLE schema_info (| .
 
 697       qq|  itime timestamp DEFAULT now(), | .
 
 698       qq|  PRIMARY KEY (tag))|;
 
 699     $dbh->do($query) || $form->dberror($query);
 
 702   $main::lxdebug->leave_sub();
 
 706   $main::lxdebug->enter_sub();
 
 708   my ($self, $form) = @_;
 
 712   $form->{sid} = $form->{dbdefault};
 
 714   my @upgradescripts = ();
 
 718   if ($form->{dbupdate}) {
 
 720     # read update scripts into memory
 
 721     opendir(SQLDIR, "sql/" . $form->{dbdriver} . "-upgrade")
 
 722       or &error("", "sql/" . $form->{dbdriver} . "-upgrade : $!");
 
 724       sort(cmp_script_version
 
 725            grep(/$form->{dbdriver}-upgrade-.*?\.(sql|pl)$/,
 
 730   my $db_charset = $main::dbcharset;
 
 731   $db_charset ||= Common::DEFAULT_CHARSET;
 
 733   foreach my $db (split(/ /, $form->{dbupdate})) {
 
 735     next unless $form->{$db};
 
 737     # strip db from dataset
 
 739     &dbconnect_vars($form, $db);
 
 742       DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 745     $dbh->do($form->{dboptions}) if ($form->{dboptions});
 
 748     $query = qq|SELECT version FROM defaults|;
 
 749     my ($version) = selectrow_query($form, $dbh, $query);
 
 751     next unless $version;
 
 753     $version = calc_version($version);
 
 755     foreach my $upgradescript (@upgradescripts) {
 
 756       my $a = $upgradescript;
 
 757       $a =~ s/^\Q$form->{dbdriver}\E-upgrade-|\.(sql|pl)$//g;
 
 760       my ($mindb, $maxdb) = split /-/, $a;
 
 761       my $str_maxdb = $maxdb;
 
 762       $mindb = calc_version($mindb);
 
 763       $maxdb = calc_version($maxdb);
 
 765       next if ($version >= $maxdb);
 
 767       # if there is no upgrade script exit
 
 768       last if ($version < $mindb);
 
 771       $main::lxdebug->message(LXDebug::DEBUG2, "Applying Update $upgradescript");
 
 772       if ($file_type eq "sql") {
 
 773         $self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 774                              "-upgrade/$upgradescript", $str_maxdb, $db_charset);
 
 776         $self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 777                                    "-upgrade/$upgradescript", $str_maxdb, $db_charset);
 
 789   $main::lxdebug->leave_sub();
 
 795   $main::lxdebug->enter_sub();
 
 797   my ($self, $form, $controls) = @_;
 
 799   $form->{sid} = $form->{dbdefault};
 
 801   my @upgradescripts = ();
 
 802   my ($query, $sth, $tag);
 
 805   @upgradescripts = sort_dbupdate_controls($controls);
 
 807   my $db_charset = $main::dbcharset;
 
 808   $db_charset ||= Common::DEFAULT_CHARSET;
 
 810   foreach my $db (split / /, $form->{dbupdate}) {
 
 812     next unless $form->{$db};
 
 814     # strip db from dataset
 
 816     &dbconnect_vars($form, $db);
 
 819       DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 822     $dbh->do($form->{dboptions}) if ($form->{dboptions});
 
 824     map({ $_->{"applied"} = 0; } @upgradescripts);
 
 826     $self->create_schema_info_table($form, $dbh);
 
 828     $query = qq|SELECT tag FROM schema_info|;
 
 829     $sth = $dbh->prepare($query);
 
 830     $sth->execute() || $form->dberror($query);
 
 831     while (($tag) = $sth->fetchrow_array()) {
 
 832       $controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
 
 837     foreach (@upgradescripts) {
 
 838       if (!$_->{"applied"}) {
 
 844     next if ($all_applied);
 
 846     foreach my $control (@upgradescripts) {
 
 847       next if ($control->{"applied"});
 
 849       $control->{description} = SL::Iconv::convert($control->{charset}, $db_charset, $control->{description});
 
 851       $control->{"file"} =~ /\.(sql|pl)$/;
 
 855       $main::lxdebug->message(LXDebug::DEBUG2, "Applying Update $control->{file}");
 
 856       print $form->parse_html_template("dbupgrade/upgrade_message2", $control);
 
 858       if ($file_type eq "sql") {
 
 859         $self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 860                              "-upgrade2/$control->{file}", $control, $db_charset);
 
 862         $self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 863                                    "-upgrade2/$control->{file}", $control, $db_charset);
 
 872   $main::lxdebug->leave_sub();
 
 877 sub update2_available {
 
 878   $main::lxdebug->enter_sub();
 
 880   my ($form, $controls) = @_;
 
 882   map({ $_->{"applied"} = 0; } values(%{$controls}));
 
 884   dbconnect_vars($form, $form->{"dbname"});
 
 887     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) ||
 
 890   my ($query, $tag, $sth);
 
 892   $query = qq|SELECT tag FROM schema_info|;
 
 893   $sth = $dbh->prepare($query);
 
 894   if ($sth->execute()) {
 
 895     while (($tag) = $sth->fetchrow_array()) {
 
 896       $controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
 
 902   map({ $main::lxdebug->leave_sub() and return 1 if (!$_->{"applied"}) }
 
 903       values(%{$controls}));
 
 905   $main::lxdebug->leave_sub();
 
 910   $main::lxdebug->enter_sub();
 
 914   # format dbconnect and dboptions string
 
 915   dbconnect_vars($self, $self->{dbname});
 
 917   map { $self->{$_} =~ s/\r//g; } qw(address signature);
 
 919   $main::auth->save_user($self->{login}, map { $_, $self->{$_} } config_vars());
 
 921   my $dbh = DBI->connect($self->{dbconnect}, $self->{dbuser}, $self->{dbpasswd});
 
 923     $self->create_employee_entry($form, $dbh, $self);
 
 927   $main::lxdebug->leave_sub();
 
 930 sub create_employee_entry {
 
 931   $main::lxdebug->enter_sub();
 
 936   my $myconfig = shift;
 
 938   # add login to employee table if it does not exist
 
 939   # no error check for employee table, ignore if it does not exist
 
 940   my ($login)  = selectrow_query($form, $dbh, qq|SELECT id FROM employee WHERE login = ?|, $self->{login});
 
 943     $query = qq|INSERT INTO employee (login, name, workphone, role) VALUES (?, ?, ?, ?)|;
 
 944     do_query($form, $dbh, $query, ($self->{login}, $myconfig->{name}, $myconfig->{tel}, "user"));
 
 947   $main::lxdebug->leave_sub();
 
 951   $main::lxdebug->enter_sub();
 
 953   my @conf = qw(acs address admin businessnumber company countrycode
 
 954     currency dateformat dbconnect dbdriver dbhost dbport dboptions
 
 955     dbname dbuser dbpasswd email fax name numberformat password
 
 956     printer role sid signature stylesheet tel templates vclimit angebote
 
 957     bestellungen rechnungen anfragen lieferantenbestellungen einkaufsrechnungen
 
 958     taxnumber co_ustid duns menustyle template_format default_media
 
 959     default_printer_id copies show_form_details favorites
 
 960     pdonumber sdonumber);
 
 962   $main::lxdebug->leave_sub();
 
 968   $main::lxdebug->enter_sub();
 
 970   my ($self, $msg) = @_;
 
 972   $main::lxdebug->show_backtrace();
 
 974   if ($ENV{HTTP_USER_AGENT}) {
 
 975     print qq|Content-Type: text/html
 
 977 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
 
 979 <body bgcolor=ffffff>
 
 981 <h2><font color=red>Error!</font></h2>
 
 988   $main::lxdebug->leave_sub();