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();
 
 314 sub dbclusterencoding {
 
 315   $main::lxdebug->enter_sub();
 
 317   my ($self, $form) = @_;
 
 319   $form->{dbdefault} ||= $form->{dbuser};
 
 321   dbconnect_vars($form, $form->{dbdefault});
 
 323   my $dbh                = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) || $form->dberror();
 
 324   my $query              = qq|SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = 'template0'|;
 
 325   my ($cluster_encoding) = $dbh->selectrow_array($query);
 
 328   $main::lxdebug->leave_sub();
 
 330   return $cluster_encoding;
 
 334   $main::lxdebug->enter_sub();
 
 336   my ($self, $form) = @_;
 
 338   $form->{sid} = $form->{dbdefault};
 
 339   &dbconnect_vars($form, $form->{dbdefault});
 
 341     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 343   $form->{db} =~ s/\"//g;
 
 345     'Pg'     => qq|CREATE DATABASE "$form->{db}"|,
 
 347     qq|CREATE USER "$form->{db}" DEFAULT TABLESPACE USERS | .
 
 348     qq|TEMPORARY TABLESPACE TEMP IDENTIFIED BY "$form->{db}"|
 
 355   push(@{$dboptions{"Pg"}}, "ENCODING = " . $dbh->quote($form->{"encoding"}))
 
 356     if ($form->{"encoding"});
 
 357   if ($form->{"dbdefault"}) {
 
 358     my $dbdefault = $form->{"dbdefault"};
 
 359     $dbdefault =~ s/[^a-zA-Z0-9_\-]//g;
 
 360     push(@{$dboptions{"Pg"}}, "TEMPLATE = $dbdefault");
 
 363   my $query = $dbcreate{$form->{dbdriver}};
 
 364   $query .= " WITH " . join(" ", @{$dboptions{"Pg"}}) if (@{$dboptions{"Pg"}});
 
 366   # Ignore errors if the database exists.
 
 369   if ($form->{dbdriver} eq 'Oracle') {
 
 370     $query = qq|GRANT CONNECT, RESOURCE TO "$form->{db}"|;
 
 371     do_query($form, $dbh, $query);
 
 375   # setup variables for the new database
 
 376   if ($form->{dbdriver} eq 'Oracle') {
 
 377     $form->{dbuser}   = $form->{db};
 
 378     $form->{dbpasswd} = $form->{db};
 
 381   &dbconnect_vars($form, $form->{db});
 
 383   $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 386   my $db_charset = $Common::db_encoding_to_charset{$form->{encoding}};
 
 387   $db_charset ||= Common::DEFAULT_CHARSET;
 
 390   $self->process_query($form, $dbh, "sql/lx-office.sql", undef, $db_charset);
 
 392   # load chart of accounts
 
 393   $self->process_query($form, $dbh, "sql/$form->{chart}-chart.sql", undef, $db_charset);
 
 395   $query = "UPDATE defaults SET coa = ?";
 
 396   do_query($form, $dbh, $query, $form->{chart});
 
 400   $main::lxdebug->leave_sub();
 
 403 # Process a Perl script which updates the database.
 
 404 # If the script returns 1 then the update was successful.
 
 405 # Return code "2" means "needs more interaction; remove
 
 406 # users/nologin and exit".
 
 407 # All other return codes are fatal errors.
 
 408 sub process_perl_script {
 
 409   $main::lxdebug->enter_sub();
 
 411   my ($self, $form, $dbh, $filename, $version_or_control, $db_charset) = @_;
 
 413   my $fh = IO::File->new($filename, "r") or $form->error("$filename : $!\n");
 
 415   my $file_charset = Common::DEFAULT_CHARSET;
 
 417   if (ref($version_or_control) eq "HASH") {
 
 418     $file_charset = $version_or_control->{charset};
 
 423       next if !/^--\s*\@charset:\s*(.+)/;
 
 427     $fh->seek(0, SEEK_SET);
 
 430   my $contents = join "", <$fh>;
 
 433   $db_charset ||= Common::DEFAULT_CHARSET;
 
 435   my $iconv = SL::Iconv::get_converter($file_charset, $db_charset);
 
 439   my %dbup_myconfig = ();
 
 440   map({ $dbup_myconfig{$_} = $form->{$_}; }
 
 441       qw(dbname dbuser dbpasswd dbhost dbport dbconnect));
 
 443   my $nls_file = $filename;
 
 444   $nls_file =~ s|.*/||;
 
 445   $nls_file =~ s|.pl$||;
 
 446   my $dbup_locale = Locale->new($main::language, $nls_file);
 
 448   my $result = eval($contents);
 
 455   if (!defined($result)) {
 
 456     print $form->parse_html_template("dbupgrade/error",
 
 457                                      { "file"  => $filename,
 
 460   } elsif (1 != $result) {
 
 461     unlink("users/nologin") if (2 == $result);
 
 465   if (ref($version_or_control) eq "HASH") {
 
 466     $dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
 
 467              $dbh->quote($version_or_control->{"tag"}) . ", " .
 
 468              $dbh->quote($form->{"login"}) . ")");
 
 469   } elsif ($version_or_control) {
 
 470     $dbh->do("UPDATE defaults SET version = " .
 
 471              $dbh->quote($version_or_control));
 
 475   $main::lxdebug->leave_sub();
 
 479   $main::lxdebug->enter_sub();
 
 481   my ($self, $form, $dbh, $filename, $version_or_control, $db_charset) = @_;
 
 483   my $fh = IO::File->new($filename, "r") or $form->error("$filename : $!\n");
 
 488   my $file_charset = Common::DEFAULT_CHARSET;
 
 491     next if !/^--\s*\@charset:\s*(.+)/;
 
 495   $fh->seek(0, SEEK_SET);
 
 497   $db_charset ||= Common::DEFAULT_CHARSET;
 
 502     $_ = SL::Iconv::convert($file_charset, $db_charset, $_);
 
 504     # Remove DOS and Unix style line endings.
 
 510     for (my $i = 0; $i < length($_); $i++) {
 
 511       my $char = substr($_, $i, 1);
 
 513       # Are we inside a string?
 
 515         if ($char eq $quote_chars[-1]) {
 
 521         if (($char eq "'") || ($char eq "\"")) {
 
 522           push(@quote_chars, $char);
 
 524         } elsif ($char eq ";") {
 
 526           # Query is complete. Send it.
 
 528           $sth = $dbh->prepare($query);
 
 529           if (!$sth->execute()) {
 
 530             my $errstr = $dbh->errstr;
 
 533             $form->dberror("The database update/creation did not succeed. " .
 
 534                            "The file ${filename} containing the following " .
 
 535                            "query failed:<br>${query}<br>" .
 
 536                            "The error message was: ${errstr}<br>" .
 
 537                            "All changes in that file have been reverted.");
 
 550   if (ref($version_or_control) eq "HASH") {
 
 551     $dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
 
 552              $dbh->quote($version_or_control->{"tag"}) . ", " .
 
 553              $dbh->quote($form->{"login"}) . ")");
 
 554   } elsif ($version_or_control) {
 
 555     $dbh->do("UPDATE defaults SET version = " .
 
 556              $dbh->quote($version_or_control));
 
 562   $main::lxdebug->leave_sub();
 
 566   $main::lxdebug->enter_sub();
 
 568   my ($self, $form) = @_;
 
 569   $form->{db} =~ s/\"//g;
 
 570   my %dbdelete = ('Pg'     => qq|DROP DATABASE "$form->{db}"|,
 
 571                   'Oracle' => qq|DROP USER "$form->{db}" CASCADE|);
 
 573   $form->{sid} = $form->{dbdefault};
 
 574   &dbconnect_vars($form, $form->{dbdefault});
 
 576     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 578   my $query = $dbdelete{$form->{dbdriver}};
 
 579   do_query($form, $dbh, $query);
 
 583   $main::lxdebug->leave_sub();
 
 586 sub dbsources_unused {
 
 587   $main::lxdebug->enter_sub();
 
 589   my ($self, $form) = @_;
 
 591   $form->{only_acc_db} = 1;
 
 593   my %members = $main::auth->read_all_users();
 
 594   my %dbexcl  = map { $_ => 1 } grep { $_ } map { $_->{dbname} } values %members;
 
 596   $dbexcl{$form->{dbdefault}}             = 1;
 
 597   $dbexcl{$main::auth->{DB_config}->{db}} = 1;
 
 599   my @dbunused = grep { !$dbexcl{$_} } dbsources("", $form);
 
 601   $main::lxdebug->leave_sub();
 
 607   $main::lxdebug->enter_sub();
 
 609   my ($self, $form) = @_;
 
 611   my %members  = $main::auth->read_all_users();
 
 612   my $controls = parse_dbupdate_controls($form, $form->{dbdriver});
 
 614   my ($query, $sth, %dbs_needing_updates);
 
 616   foreach my $login (grep /[a-z]/, keys %members) {
 
 617     my $member = $members{$login};
 
 619     map { $form->{$_} = $member->{$_} } qw(dbname dbuser dbpasswd dbhost dbport);
 
 620     dbconnect_vars($form, $form->{dbname});
 
 622     my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd});
 
 628     $query = qq|SELECT version FROM defaults|;
 
 629     $sth = prepare_query($form, $dbh, $query);
 
 630     if ($sth->execute()) {
 
 631       ($version) = $sth->fetchrow_array();
 
 636     next unless $version;
 
 638     if (update_available($form->{dbdriver}, $version) || update2_available($form, $controls)) {
 
 640       map { $dbinfo->{$_} = $member->{$_} } grep /^db/, keys %{ $member };
 
 641       $dbs_needing_updates{$member->{dbhost} . "::" . $member->{dbname}} = $dbinfo;
 
 645   $main::lxdebug->leave_sub();
 
 647   return values %dbs_needing_updates;
 
 651   $main::lxdebug->enter_sub(2);
 
 653   my (@v, $version, $i);
 
 655   @v = split(/\./, $_[0]);
 
 656   while (scalar(@v) < 4) {
 
 660   for ($i = 0; $i < 4; $i++) {
 
 665   $main::lxdebug->leave_sub(2);
 
 669 sub cmp_script_version {
 
 670   my ($a_from, $a_to, $b_from, $b_to);
 
 671   my ($i, $res_a, $res_b);
 
 672   my ($my_a, $my_b) = ($a, $b);
 
 674   $my_a =~ s/.*-upgrade-//;
 
 676   $my_b =~ s/.*-upgrade-//;
 
 678   ($my_a_from, $my_a_to) = split(/-/, $my_a);
 
 679   ($my_b_from, $my_b_to) = split(/-/, $my_b);
 
 681   $res_a = calc_version($my_a_from);
 
 682   $res_b = calc_version($my_b_from);
 
 684   if ($res_a == $res_b) {
 
 685     $res_a = calc_version($my_a_to);
 
 686     $res_b = calc_version($my_b_to);
 
 689   return $res_a <=> $res_b;
 
 692 sub update_available {
 
 693   my ($dbdriver, $cur_version) = @_;
 
 697   opendir SQLDIR, "sql/${dbdriver}-upgrade" || error("", "sql/${dbdriver}-upgrade: $!");
 
 698   my @upgradescripts = grep /${dbdriver}-upgrade-\Q$cur_version\E.*\.(sql|pl)$/, readdir SQLDIR;
 
 701   return ($#upgradescripts > -1);
 
 704 sub create_schema_info_table {
 
 705   $main::lxdebug->enter_sub();
 
 707   my ($self, $form, $dbh) = @_;
 
 709   my $query = "SELECT tag FROM schema_info LIMIT 1";
 
 710   if (!$dbh->do($query)) {
 
 713       qq|CREATE TABLE schema_info (| .
 
 716       qq|  itime timestamp DEFAULT now(), | .
 
 717       qq|  PRIMARY KEY (tag))|;
 
 718     $dbh->do($query) || $form->dberror($query);
 
 721   $main::lxdebug->leave_sub();
 
 725   $main::lxdebug->enter_sub();
 
 727   my ($self, $form) = @_;
 
 731   $form->{sid} = $form->{dbdefault};
 
 733   my @upgradescripts = ();
 
 737   if ($form->{dbupdate}) {
 
 739     # read update scripts into memory
 
 740     opendir(SQLDIR, "sql/" . $form->{dbdriver} . "-upgrade")
 
 741       or &error("", "sql/" . $form->{dbdriver} . "-upgrade : $!");
 
 743       sort(cmp_script_version
 
 744            grep(/$form->{dbdriver}-upgrade-.*?\.(sql|pl)$/,
 
 749   my $db_charset = $main::dbcharset;
 
 750   $db_charset ||= Common::DEFAULT_CHARSET;
 
 752   foreach my $db (split(/ /, $form->{dbupdate})) {
 
 754     next unless $form->{$db};
 
 756     # strip db from dataset
 
 758     &dbconnect_vars($form, $db);
 
 761       DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 764     $dbh->do($form->{dboptions}) if ($form->{dboptions});
 
 767     $query = qq|SELECT version FROM defaults|;
 
 768     my ($version) = selectrow_query($form, $dbh, $query);
 
 770     next unless $version;
 
 772     $version = calc_version($version);
 
 774     foreach my $upgradescript (@upgradescripts) {
 
 775       my $a = $upgradescript;
 
 776       $a =~ s/^\Q$form->{dbdriver}\E-upgrade-|\.(sql|pl)$//g;
 
 779       my ($mindb, $maxdb) = split /-/, $a;
 
 780       my $str_maxdb = $maxdb;
 
 781       $mindb = calc_version($mindb);
 
 782       $maxdb = calc_version($maxdb);
 
 784       next if ($version >= $maxdb);
 
 786       # if there is no upgrade script exit
 
 787       last if ($version < $mindb);
 
 790       $main::lxdebug->message(LXDebug::DEBUG2, "Applying Update $upgradescript");
 
 791       if ($file_type eq "sql") {
 
 792         $self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 793                              "-upgrade/$upgradescript", $str_maxdb, $db_charset);
 
 795         $self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 796                                    "-upgrade/$upgradescript", $str_maxdb, $db_charset);
 
 808   $main::lxdebug->leave_sub();
 
 814   $main::lxdebug->enter_sub();
 
 816   my ($self, $form, $controls) = @_;
 
 818   $form->{sid} = $form->{dbdefault};
 
 820   my @upgradescripts = ();
 
 821   my ($query, $sth, $tag);
 
 824   @upgradescripts = sort_dbupdate_controls($controls);
 
 826   my $db_charset = $main::dbcharset;
 
 827   $db_charset ||= Common::DEFAULT_CHARSET;
 
 829   foreach my $db (split / /, $form->{dbupdate}) {
 
 831     next unless $form->{$db};
 
 833     # strip db from dataset
 
 835     &dbconnect_vars($form, $db);
 
 838       DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
 
 841     $dbh->do($form->{dboptions}) if ($form->{dboptions});
 
 843     map({ $_->{"applied"} = 0; } @upgradescripts);
 
 845     $self->create_schema_info_table($form, $dbh);
 
 847     $query = qq|SELECT tag FROM schema_info|;
 
 848     $sth = $dbh->prepare($query);
 
 849     $sth->execute() || $form->dberror($query);
 
 850     while (($tag) = $sth->fetchrow_array()) {
 
 851       $controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
 
 856     foreach (@upgradescripts) {
 
 857       if (!$_->{"applied"}) {
 
 863     next if ($all_applied);
 
 865     foreach my $control (@upgradescripts) {
 
 866       next if ($control->{"applied"});
 
 868       $control->{description} = SL::Iconv::convert($control->{charset}, $db_charset, $control->{description});
 
 870       $control->{"file"} =~ /\.(sql|pl)$/;
 
 874       $main::lxdebug->message(LXDebug::DEBUG2, "Applying Update $control->{file}");
 
 875       print $form->parse_html_template("dbupgrade/upgrade_message2", $control);
 
 877       if ($file_type eq "sql") {
 
 878         $self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 879                              "-upgrade2/$control->{file}", $control, $db_charset);
 
 881         $self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} .
 
 882                                    "-upgrade2/$control->{file}", $control, $db_charset);
 
 891   $main::lxdebug->leave_sub();
 
 896 sub update2_available {
 
 897   $main::lxdebug->enter_sub();
 
 899   my ($form, $controls) = @_;
 
 901   map({ $_->{"applied"} = 0; } values(%{$controls}));
 
 903   dbconnect_vars($form, $form->{"dbname"});
 
 906     DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) ||
 
 909   my ($query, $tag, $sth);
 
 911   $query = qq|SELECT tag FROM schema_info|;
 
 912   $sth = $dbh->prepare($query);
 
 913   if ($sth->execute()) {
 
 914     while (($tag) = $sth->fetchrow_array()) {
 
 915       $controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
 
 921   map({ $main::lxdebug->leave_sub() and return 1 if (!$_->{"applied"}) }
 
 922       values(%{$controls}));
 
 924   $main::lxdebug->leave_sub();
 
 929   $main::lxdebug->enter_sub();
 
 933   # format dbconnect and dboptions string
 
 934   dbconnect_vars($self, $self->{dbname});
 
 936   map { $self->{$_} =~ s/\r//g; } qw(address signature);
 
 938   $main::auth->save_user($self->{login}, map { $_, $self->{$_} } config_vars());
 
 940   my $dbh = DBI->connect($self->{dbconnect}, $self->{dbuser}, $self->{dbpasswd});
 
 942     $self->create_employee_entry($form, $dbh, $self);
 
 946   $main::lxdebug->leave_sub();
 
 949 sub create_employee_entry {
 
 950   $main::lxdebug->enter_sub();
 
 955   my $myconfig = shift;
 
 957   # add login to employee table if it does not exist
 
 958   # no error check for employee table, ignore if it does not exist
 
 959   my ($login)  = selectrow_query($form, $dbh, qq|SELECT id FROM employee WHERE login = ?|, $self->{login});
 
 962     $query = qq|INSERT INTO employee (login, name, workphone, role) VALUES (?, ?, ?, ?)|;
 
 963     do_query($form, $dbh, $query, ($self->{login}, $myconfig->{name}, $myconfig->{tel}, "user"));
 
 966   $main::lxdebug->leave_sub();
 
 970   $main::lxdebug->enter_sub();
 
 972   my @conf = qw(acs address admin businessnumber company countrycode
 
 973     currency dateformat dbconnect dbdriver dbhost dbport dboptions
 
 974     dbname dbuser dbpasswd email fax name numberformat password
 
 975     printer role sid signature stylesheet tel templates vclimit angebote
 
 976     bestellungen rechnungen anfragen lieferantenbestellungen einkaufsrechnungen
 
 977     taxnumber co_ustid duns menustyle template_format default_media
 
 978     default_printer_id copies show_form_details favorites
 
 979     pdonumber sdonumber);
 
 981   $main::lxdebug->leave_sub();
 
 987   $main::lxdebug->enter_sub();
 
 989   my ($self, $msg) = @_;
 
 991   $main::lxdebug->show_backtrace();
 
 993   if ($ENV{HTTP_USER_AGENT}) {
 
 994     print qq|Content-Type: text/html
 
 996 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
 
 998 <body bgcolor=ffffff>
 
1000 <h2><font color=red>Error!</font></h2>
 
1005   die "Error: $msg\n";
 
1007   $main::lxdebug->leave_sub();