Projekt

Allgemein

Profil

Herunterladen (26,3 KB) Statistiken
| Zweig: | Markierung: | Revision:
d319704a Moritz Bunkus
#=====================================================================
# LX-Office ERP
# Copyright (C) 2004
# Based on SQL-Ledger Version 2.1.9
# Web http://www.lx-office.org
#
#=====================================================================
# SQL-Ledger Accounting
# Copyright (C) 2001
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
# Web: http://www.sql-ledger.org
#
# Contributors:
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY 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 this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#=====================================================================
#
# user related functions
#
#=====================================================================

package User;

05fd99ac Sven Schöling
#use strict;
b8da8785 Sven Schöling
faef45c2 Moritz Bunkus
use IO::File;
use Fcntl qw(:seek);

8c7e4493 Moritz Bunkus
use SL::Auth;
4fd8bdbf Moritz Bunkus
use SL::DBUpgrade2;
f7057756 Moritz Bunkus
use SL::DBUtils;
a200453a Moritz Bunkus
use SL::Iconv;
0b280f98 Moritz Bunkus
use SL::Inifile;
4fd8bdbf Moritz Bunkus
d319704a Moritz Bunkus
sub new {
$main::lxdebug->enter_sub();

8c7e4493 Moritz Bunkus
my ($type, $login) = @_;

d319704a Moritz Bunkus
my $self = {};

if ($login ne "") {
8c7e4493 Moritz Bunkus
my %user_data = $main::auth->read_user($login);
map { $self->{$_} = $user_data{$_} } keys %user_data;
d319704a Moritz Bunkus
}

$main::lxdebug->leave_sub();
8c7e4493 Moritz Bunkus
d319704a Moritz Bunkus
bless $self, $type;
}

sub country_codes {
$main::lxdebug->enter_sub();

8e6eda05 Moritz Bunkus
local *DIR;

d319704a Moritz Bunkus
my %cc = ();
my @language = ();

# scan the locale directory and read in the LANGUAGE files
f7057756 Moritz Bunkus
opendir(DIR, "locale");
d319704a Moritz Bunkus
f7057756 Moritz Bunkus
my @dir = grep(!/(^\.\.?$|\..*)/, readdir(DIR));
d319704a Moritz Bunkus
foreach my $dir (@dir) {
next unless open(FH, "locale/$dir/LANGUAGE");
@language = <FH>;
close FH;

$cc{$dir} = "@language";
}

closedir(DIR);

$main::lxdebug->leave_sub();

return %cc;
}

sub login {
$main::lxdebug->enter_sub();

8c7e4493 Moritz Bunkus
my ($self, $form) = @_;
b8da8785 Sven Schöling
our $sid;
d319704a Moritz Bunkus
8e6eda05 Moritz Bunkus
local *FH;

d319704a Moritz Bunkus
my $rc = -3;

if ($self->{login}) {
8c7e4493 Moritz Bunkus
my %myconfig = $main::auth->read_user($self->{login});
d319704a Moritz Bunkus
# check if database is down
my $dbh =
DBI->connect($myconfig{dbconnect}, $myconfig{dbuser},
$myconfig{dbpasswd})
or $self->error(DBI::errstr);

# we got a connection, check the version
my $query = qq|SELECT version FROM defaults|;
my $sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);

my ($dbversion) = $sth->fetchrow_array;
$sth->finish;

8c7e4493 Moritz Bunkus
$self->create_employee_entry($form, $dbh, \%myconfig);
4fd8bdbf Moritz Bunkus
$self->create_schema_info_table($form, $dbh);

d319704a Moritz Bunkus
$dbh->disconnect;

$rc = 0;

4fd8bdbf Moritz Bunkus
my $controls =
parse_dbupdate_controls($form, $myconfig{"dbdriver"});
d319704a Moritz Bunkus
4fd8bdbf Moritz Bunkus
map({ $form->{$_} = $myconfig{$_} }
8c7e4493 Moritz Bunkus
qw(dbname dbhost dbport dbdriver dbuser dbpasswd dbconnect dateformat));
4fd8bdbf Moritz Bunkus
if (update_available($myconfig{"dbdriver"}, $dbversion) ||
update2_available($form, $controls)) {
d319704a Moritz Bunkus
d69fdcda Moritz Bunkus
$form->{"stylesheet"} = "lx-office-erp.css";
$form->{"title"} = $main::locale->text("Dataset upgrade");
$form->header();
9aaca433 Moritz Bunkus
print $form->parse_html_template("dbupgrade/header");
aa6ce434 Moritz Bunkus
$form->{dbupdate} = "db$myconfig{dbname}";
$form->{ $form->{dbupdate} } = 1;

a7ae494b Moritz Bunkus
if ($form->{"show_dbupdate_warning"}) {
9aaca433 Moritz Bunkus
print $form->parse_html_template("dbupgrade/warning");
aa6ce434 Moritz Bunkus
exit(0);
}

# update the tables
52cd76db Moritz Bunkus
if (!open(FH, ">$main::userspath/nologin")) {
$form->show_generic_error($main::locale->text('A temporary file could not be created. ' .
'Please verify that the directory "#1" is writeable by the webserver.',
$main::userspath),
'back_button' => 1);
}
d319704a Moritz Bunkus
# required for Oracle
$form->{dbdefault} = $sid;

# ignore HUP, QUIT in case the webserver times out
$SIG{HUP} = 'IGNORE';
$SIG{QUIT} = 'IGNORE';

$self->dbupdate($form);
4fd8bdbf Moritz Bunkus
$self->dbupdate2($form, $controls);
d319704a Moritz Bunkus
8e6eda05 Moritz Bunkus
close(FH);

d319704a Moritz Bunkus
# remove lock file
8c7e4493 Moritz Bunkus
unlink("$main::userspath/nologin");
d319704a Moritz Bunkus
e9b15b28 Moritz Bunkus
my $menufile =
$self->{"menustyle"} eq "v3" ? "menuv3.pl" :
$self->{"menustyle"} eq "neu" ? "menunew.pl" :
ee356ccc Holger Lindemann
$self->{"menustyle"} eq "js" ? "menujs.pl" :
f559ec45 Holger Will
$self->{"menustyle"} eq "xml" ? "menuXML.pl" :
e9b15b28 Moritz Bunkus
"menu.pl";

9aaca433 Moritz Bunkus
print $form->parse_html_template("dbupgrade/footer", { "menufile" => $menufile });
d319704a Moritz Bunkus
$rc = -2;

}
}

$main::lxdebug->leave_sub();

return $rc;
}

sub dbconnect_vars {
$main::lxdebug->enter_sub();

my ($form, $db) = @_;

my %dboptions = (
'Pg' => { 'yy-mm-dd' => 'set DateStyle to \'ISO\'',
'yyyy-mm-dd' => 'set DateStyle to \'ISO\'',
'mm/dd/yy' => 'set DateStyle to \'SQL, US\'',
'mm-dd-yy' => 'set DateStyle to \'POSTGRES, US\'',
'dd/mm/yy' => 'set DateStyle to \'SQL, EUROPEAN\'',
'dd-mm-yy' => 'set DateStyle to \'POSTGRES, EUROPEAN\'',
'dd.mm.yy' => 'set DateStyle to \'GERMAN\''
},
'Oracle' => {
'yy-mm-dd' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'YY-MM-DD\'',
'yyyy-mm-dd' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'YYYY-MM-DD\'',
'mm/dd/yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'MM/DD/YY\'',
'mm-dd-yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'MM-DD-YY\'',
'dd/mm/yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD/MM/YY\'',
'dd-mm-yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD-MM-YY\'',
'dd.mm.yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD.MM.YY\'',
});

$form->{dboptions} = $dboptions{ $form->{dbdriver} }{ $form->{dateformat} };

if ($form->{dbdriver} eq 'Pg') {
$form->{dbconnect} = "dbi:Pg:dbname=$db";
}

if ($form->{dbdriver} eq 'Oracle') {
$form->{dbconnect} = "dbi:Oracle:sid=$form->{sid}";
}

if ($form->{dbhost}) {
$form->{dbconnect} .= ";host=$form->{dbhost}";
}
if ($form->{dbport}) {
$form->{dbconnect} .= ";port=$form->{dbport}";
}

$main::lxdebug->leave_sub();
}

sub dbdrivers {
$main::lxdebug->enter_sub();

my @drivers = DBI->available_drivers();

$main::lxdebug->leave_sub();

return (grep { /(Pg|Oracle)/ } @drivers);
}

sub dbsources {
$main::lxdebug->enter_sub();

my ($self, $form) = @_;

my @dbsources = ();
my ($sth, $query);

$form->{dbdefault} = $form->{dbuser} unless $form->{dbdefault};
$form->{sid} = $form->{dbdefault};
&dbconnect_vars($form, $form->{dbdefault});

my $dbh =
DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
or $form->dberror;

if ($form->{dbdriver} eq 'Pg') {
f7057756 Moritz Bunkus
$query =
qq|SELECT datname FROM pg_database | .
qq|WHERE NOT datname IN ('template0', 'template1')|;
$sth = $dbh->prepare($query);
$sth->execute() || $form->dberror($query);
d319704a Moritz Bunkus
while (my ($db) = $sth->fetchrow_array) {

if ($form->{only_acc_db}) {

next if ($db =~ /^template/);

&dbconnect_vars($form, $db);
my $dbh =
DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
or $form->dberror;

f7057756 Moritz Bunkus
$query =
qq|SELECT tablename FROM pg_tables | .
qq|WHERE (tablename = 'defaults') AND (tableowner = ?)|;
d319704a Moritz Bunkus
my $sth = $dbh->prepare($query);
f7057756 Moritz Bunkus
$sth->execute($form->{dbuser}) ||
$form->dberror($query . " ($form->{dbuser})");
d319704a Moritz Bunkus
if ($sth->fetchrow_array) {
f7057756 Moritz Bunkus
push(@dbsources, $db);
d319704a Moritz Bunkus
}
$sth->finish;
$dbh->disconnect;
next;
}
f7057756 Moritz Bunkus
push(@dbsources, $db);
d319704a Moritz Bunkus
}
}

if ($form->{dbdriver} eq 'Oracle') {
if ($form->{only_acc_db}) {
f7057756 Moritz Bunkus
$query =
qq|SELECT owner FROM dba_objects | .
qq|WHERE object_name = 'DEFAULTS' AND object_type = 'TABLE'|;
d319704a Moritz Bunkus
} else {
$query = qq|SELECT username FROM dba_users|;
}

$sth = $dbh->prepare($query);
$sth->execute || $form->dberror($query);

while (my ($db) = $sth->fetchrow_array) {
f7057756 Moritz Bunkus
push(@dbsources, $db);
d319704a Moritz Bunkus
}
}

$sth->finish;
$dbh->disconnect;

$main::lxdebug->leave_sub();

return @dbsources;
}

c87608ab Moritz Bunkus
sub dbclusterencoding {
$main::lxdebug->enter_sub();

my ($self, $form) = @_;

$form->{dbdefault} ||= $form->{dbuser};

dbconnect_vars($form, $form->{dbdefault});

my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) || $form->dberror();
my $query = qq|SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = 'template0'|;
my ($cluster_encoding) = $dbh->selectrow_array($query);
$dbh->disconnect();

$main::lxdebug->leave_sub();

return $cluster_encoding;
}

d319704a Moritz Bunkus
sub dbcreate {
$main::lxdebug->enter_sub();

my ($self, $form) = @_;

61bd0898 Moritz Bunkus
$form->{sid} = $form->{dbdefault};
&dbconnect_vars($form, $form->{dbdefault});
my $dbh =
DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
or $form->dberror;
f7057756 Moritz Bunkus
$form->{db} =~ s/\"//g;
d319704a Moritz Bunkus
my %dbcreate = (
'Pg' => qq|CREATE DATABASE "$form->{db}"|,
'Oracle' =>
f7057756 Moritz Bunkus
qq|CREATE USER "$form->{db}" DEFAULT TABLESPACE USERS | .
qq|TEMPORARY TABLESPACE TEMP IDENTIFIED BY "$form->{db}"|
d319704a Moritz Bunkus
);

61bd0898 Moritz Bunkus
my %dboptions = (
'Pg' => [],
);

push(@{$dboptions{"Pg"}}, "ENCODING = " . $dbh->quote($form->{"encoding"}))
if ($form->{"encoding"});
if ($form->{"dbdefault"}) {
my $dbdefault = $form->{"dbdefault"};
$dbdefault =~ s/[^a-zA-Z0-9_\-]//g;
push(@{$dboptions{"Pg"}}, "TEMPLATE = $dbdefault");
}
d319704a Moritz Bunkus
f7057756 Moritz Bunkus
my $query = $dbcreate{$form->{dbdriver}};
61bd0898 Moritz Bunkus
$query .= " WITH " . join(" ", @{$dboptions{"Pg"}}) if (@{$dboptions{"Pg"}});

6b7624a4 Moritz Bunkus
# Ignore errors if the database exists.
$dbh->do($query);
d319704a Moritz Bunkus
if ($form->{dbdriver} eq 'Oracle') {
f7057756 Moritz Bunkus
$query = qq|GRANT CONNECT, RESOURCE TO "$form->{db}"|;
do_query($form, $dbh, $query);
d319704a Moritz Bunkus
}
$dbh->disconnect;

# setup variables for the new database
if ($form->{dbdriver} eq 'Oracle') {
$form->{dbuser} = $form->{db};
$form->{dbpasswd} = $form->{db};
}

&dbconnect_vars($form, $form->{db});

$dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
or $form->dberror;

faef45c2 Moritz Bunkus
my $db_charset = $Common::db_encoding_to_charset{$form->{encoding}};
$db_charset ||= Common::DEFAULT_CHARSET;

d319704a Moritz Bunkus
# create the tables
faef45c2 Moritz Bunkus
$self->process_query($form, $dbh, "sql/lx-office.sql", undef, $db_charset);
d319704a Moritz Bunkus
# load chart of accounts
faef45c2 Moritz Bunkus
$self->process_query($form, $dbh, "sql/$form->{chart}-chart.sql", undef, $db_charset);
d319704a Moritz Bunkus
f7057756 Moritz Bunkus
$query = "UPDATE defaults SET coa = ?";
do_query($form, $dbh, $query, $form->{chart});
89c9d0aa Moritz Bunkus
d319704a Moritz Bunkus
$dbh->disconnect;

$main::lxdebug->leave_sub();
}

21c607d3 Moritz Bunkus
# Process a Perl script which updates the database.
# If the script returns 1 then the update was successful.
# Return code "2" means "needs more interaction; remove
# users/nologin and exit".
# All other return codes are fatal errors.
sub process_perl_script {
$main::lxdebug->enter_sub();

faef45c2 Moritz Bunkus
my ($self, $form, $dbh, $filename, $version_or_control, $db_charset) = @_;
21c607d3 Moritz Bunkus
faef45c2 Moritz Bunkus
my $fh = IO::File->new($filename, "r") or $form->error("$filename : $!\n");

my $file_charset = Common::DEFAULT_CHARSET;

if (ref($version_or_control) eq "HASH") {
$file_charset = $version_or_control->{charset};

} else {
while (<$fh>) {
last if !/^--/;
next if !/^--\s*\@charset:\s*(.+)/;
$file_charset = $1;
last;
}
$fh->seek(0, SEEK_SET);
}

my $contents = join "", <$fh>;
$fh->close();

$db_charset ||= Common::DEFAULT_CHARSET;

a200453a Moritz Bunkus
my $iconv = SL::Iconv::get_converter($file_charset, $db_charset);
21c607d3 Moritz Bunkus
$dbh->begin_work();

ae1b5cba Moritz Bunkus
my %dbup_myconfig = ();
map({ $dbup_myconfig{$_} = $form->{$_}; }
qw(dbname dbuser dbpasswd dbhost dbport dbconnect));

my $nls_file = $filename;
$nls_file =~ s|.*/||;
$nls_file =~ s|.pl$||;
my $dbup_locale = Locale->new($main::language, $nls_file);

21c607d3 Moritz Bunkus
my $result = eval($contents);

if (1 != $result) {
$dbh->rollback();
$dbh->disconnect();
}

if (!defined($result)) {
9aaca433 Moritz Bunkus
print $form->parse_html_template("dbupgrade/error",
{ "file" => $filename,
"error" => $@ });
d69fdcda Moritz Bunkus
exit(0);
21c607d3 Moritz Bunkus
} elsif (1 != $result) {
unlink("users/nologin") if (2 == $result);
exit(0);
}

1efda319 Moritz Bunkus
if (ref($version_or_control) eq "HASH") {
$dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
$dbh->quote($version_or_control->{"tag"}) . ", " .
$dbh->quote($form->{"login"}) . ")");
} elsif ($version_or_control) {
$dbh->do("UPDATE defaults SET version = " .
$dbh->quote($version_or_control));
21c607d3 Moritz Bunkus
}
$dbh->commit();

$main::lxdebug->leave_sub();
}

d319704a Moritz Bunkus
sub process_query {
$main::lxdebug->enter_sub();

faef45c2 Moritz Bunkus
my ($self, $form, $dbh, $filename, $version_or_control, $db_charset) = @_;
d319704a Moritz Bunkus
faef45c2 Moritz Bunkus
my $fh = IO::File->new($filename, "r") or $form->error("$filename : $!\n");
d319704a Moritz Bunkus
my $query = "";
my $sth;
my @quote_chars;

faef45c2 Moritz Bunkus
my $file_charset = Common::DEFAULT_CHARSET;
while (<$fh>) {
last if !/^--/;
next if !/^--\s*\@charset:\s*(.+)/;
$file_charset = $1;
last;
}
$fh->seek(0, SEEK_SET);

$db_charset ||= Common::DEFAULT_CHARSET;

df9b211e Moritz Bunkus
$dbh->begin_work();

faef45c2 Moritz Bunkus
while (<$fh>) {
a200453a Moritz Bunkus
$_ = SL::Iconv::convert($file_charset, $db_charset, $_);
d319704a Moritz Bunkus
# Remove DOS and Unix style line endings.
4c2287d7 Moritz Bunkus
chomp;
d319704a Moritz Bunkus
4c2287d7 Moritz Bunkus
# remove comments
s/--.*$//;
d319704a Moritz Bunkus
for (my $i = 0; $i < length($_); $i++) {
my $char = substr($_, $i, 1);

# Are we inside a string?
if (@quote_chars) {
if ($char eq $quote_chars[-1]) {
pop(@quote_chars);
}
$query .= $char;

} else {
if (($char eq "'") || ($char eq "\"")) {
push(@quote_chars, $char);

} elsif ($char eq ";") {

# Query is complete. Send it.

$sth = $dbh->prepare($query);
df9b211e Moritz Bunkus
if (!$sth->execute()) {
c12ec001 Moritz Bunkus
my $errstr = $dbh->errstr;
df9b211e Moritz Bunkus
$sth->finish();
$dbh->rollback();
f7057756 Moritz Bunkus
$form->dberror("The database update/creation did not succeed. " .
"The file ${filename} containing the following " .
"query failed:<br>${query}<br>" .
c12ec001 Moritz Bunkus
"The error message was: ${errstr}<br>" .
df9b211e Moritz Bunkus
"All changes in that file have been reverted.");
}
$sth->finish();
d319704a Moritz Bunkus
$char = "";
$query = "";
}

$query .= $char;
}
}
2c5bd173 Moritz Bunkus
# Insert a space at the end of each line so that queries split
# over multiple lines work properly.
if ($query ne '') {
$query .= @quote_chars ? "\n" : ' ';
}
d319704a Moritz Bunkus
}

4fd8bdbf Moritz Bunkus
if (ref($version_or_control) eq "HASH") {
$dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
$dbh->quote($version_or_control->{"tag"}) . ", " .
$dbh->quote($form->{"login"}) . ")");
} elsif ($version_or_control) {
bd4fb92d Moritz Bunkus
$dbh->do("UPDATE defaults SET version = " .
$dbh->quote($version_or_control));
df9b211e Moritz Bunkus
}
$dbh->commit();

faef45c2 Moritz Bunkus
$fh->close();
d319704a Moritz Bunkus
$main::lxdebug->leave_sub();
}

sub dbdelete {
$main::lxdebug->enter_sub();

my ($self, $form) = @_;
f7057756 Moritz Bunkus
$form->{db} =~ s/\"//g;
d319704a Moritz Bunkus
my %dbdelete = ('Pg' => qq|DROP DATABASE "$form->{db}"|,
f7057756 Moritz Bunkus
'Oracle' => qq|DROP USER "$form->{db}" CASCADE|);
d319704a Moritz Bunkus
$form->{sid} = $form->{dbdefault};
&dbconnect_vars($form, $form->{dbdefault});
my $dbh =
DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
or $form->dberror;
f7057756 Moritz Bunkus
my $query = $dbdelete{$form->{dbdriver}};
do_query($form, $dbh, $query);
d319704a Moritz Bunkus
$dbh->disconnect;

$main::lxdebug->leave_sub();
}

sub dbsources_unused {
$main::lxdebug->enter_sub();

8c7e4493 Moritz Bunkus
my ($self, $form) = @_;
d319704a Moritz Bunkus
$form->{only_acc_db} = 1;

8c7e4493 Moritz Bunkus
my %members = $main::auth->read_all_users();
my %dbexcl = map { $_ => 1 } grep { $_ } map { $_->{dbname} } values %members;
d319704a Moritz Bunkus
8c7e4493 Moritz Bunkus
$dbexcl{$form->{dbdefault}} = 1;
$dbexcl{$main::auth->{DB_config}->{db}} = 1;

my @dbunused = grep { !$dbexcl{$_} } dbsources("", $form);
d319704a Moritz Bunkus
$main::lxdebug->leave_sub();

8c7e4493 Moritz Bunkus
return @dbunused;
d319704a Moritz Bunkus
}

sub dbneedsupdate {
$main::lxdebug->enter_sub();

my ($self, $form) = @_;

8c7e4493 Moritz Bunkus
my %members = $main::auth->read_all_users();
0b280f98 Moritz Bunkus
my $controls = parse_dbupdate_controls($form, $form->{dbdriver});
d319704a Moritz Bunkus
0b280f98 Moritz Bunkus
my ($query, $sth, %dbs_needing_updates);
d319704a Moritz Bunkus
8c7e4493 Moritz Bunkus
foreach my $login (grep /[a-z]/, keys %members) {
my $member = $members{$login};
d319704a Moritz Bunkus
0b280f98 Moritz Bunkus
map { $form->{$_} = $member->{$_} } qw(dbname dbuser dbpasswd dbhost dbport);
dbconnect_vars($form, $form->{dbname});
8c7e4493 Moritz Bunkus
0b280f98 Moritz Bunkus
my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd});
d319704a Moritz Bunkus
0b280f98 Moritz Bunkus
next unless $dbh;
d319704a Moritz Bunkus
0b280f98 Moritz Bunkus
my $version;
d319704a Moritz Bunkus
0b280f98 Moritz Bunkus
$query = qq|SELECT version FROM defaults|;
$sth = prepare_query($form, $dbh, $query);
if ($sth->execute()) {
($version) = $sth->fetchrow_array();
d319704a Moritz Bunkus
}
0b280f98 Moritz Bunkus
$sth->finish();
$dbh->disconnect();
d319704a Moritz Bunkus
0b280f98 Moritz Bunkus
next unless $version;
d319704a Moritz Bunkus
0b280f98 Moritz Bunkus
if (update_available($form->{dbdriver}, $version) || update2_available($form, $controls)) {
my $dbinfo = {};
map { $dbinfo->{$_} = $member->{$_} } grep /^db/, keys %{ $member };
$dbs_needing_updates{$member->{dbhost} . "::" . $member->{dbname}} = $dbinfo;
d319704a Moritz Bunkus
}
}

$main::lxdebug->leave_sub();

0b280f98 Moritz Bunkus
return values %dbs_needing_updates;
d319704a Moritz Bunkus
}

sub calc_version {
8c6efb2a Moritz Bunkus
$main::lxdebug->enter_sub(2);
d319704a Moritz Bunkus
my (@v, $version, $i);

@v = split(/\./, $_[0]);
while (scalar(@v) < 4) {
push(@v, 0);
}
$version = 0;
for ($i = 0; $i < 4; $i++) {
$version *= 1000;
$version += $v[$i];
}

8c6efb2a Moritz Bunkus
$main::lxdebug->leave_sub(2);
d319704a Moritz Bunkus
return $version;
}

sub cmp_script_version {
my ($a_from, $a_to, $b_from, $b_to);
my ($i, $res_a, $res_b);
my ($my_a, $my_b) = ($a, $b);

$my_a =~ s/.*-upgrade-//;
$my_a =~ s/.sql$//;
$my_b =~ s/.*-upgrade-//;
$my_b =~ s/.sql$//;
b8da8785 Sven Schöling
my ($my_a_from, $my_a_to) = split(/-/, $my_a);
my ($my_b_from, $my_b_to) = split(/-/, $my_b);
d319704a Moritz Bunkus
$res_a = calc_version($my_a_from);
$res_b = calc_version($my_b_from);

if ($res_a == $res_b) {
$res_a = calc_version($my_a_to);
$res_b = calc_version($my_b_to);
}

return $res_a <=> $res_b;
}

0d692054 Moritz Bunkus
sub update_available {
4c2287d7 Moritz Bunkus
my ($dbdriver, $cur_version) = @_;

8e6eda05 Moritz Bunkus
local *SQLDIR;

0b280f98 Moritz Bunkus
opendir SQLDIR, "sql/${dbdriver}-upgrade" || error("", "sql/${dbdriver}-upgrade: $!");
my @upgradescripts = grep /${dbdriver}-upgrade-\Q$cur_version\E.*\.(sql|pl)$/, readdir SQLDIR;
closedir SQLDIR;
4c2287d7 Moritz Bunkus
return ($#upgradescripts > -1);
0d692054 Moritz Bunkus
}

4fd8bdbf Moritz Bunkus
sub create_schema_info_table {
$main::lxdebug->enter_sub();

my ($self, $form, $dbh) = @_;

my $query = "SELECT tag FROM schema_info LIMIT 1";
if (!$dbh->do($query)) {
81b82d22 Moritz Bunkus
$dbh->rollback();
4fd8bdbf Moritz Bunkus
$query =
f7057756 Moritz Bunkus
qq|CREATE TABLE schema_info (| .
qq| tag text, | .
qq| login text, | .
qq| itime timestamp DEFAULT now(), | .
qq| PRIMARY KEY (tag))|;
4fd8bdbf Moritz Bunkus
$dbh->do($query) || $form->dberror($query);
}

$main::lxdebug->leave_sub();
}

d319704a Moritz Bunkus
sub dbupdate {
$main::lxdebug->enter_sub();

my ($self, $form) = @_;

8e6eda05 Moritz Bunkus
local *SQLDIR;

d319704a Moritz Bunkus
$form->{sid} = $form->{dbdefault};

my @upgradescripts = ();
my $query;
my $rc = -2;

if ($form->{dbupdate}) {

# read update scripts into memory
f7057756 Moritz Bunkus
opendir(SQLDIR, "sql/" . $form->{dbdriver} . "-upgrade")
or &error("", "sql/" . $form->{dbdriver} . "-upgrade : $!");
d319704a Moritz Bunkus
@upgradescripts =
sort(cmp_script_version
f7057756 Moritz Bunkus
grep(/$form->{dbdriver}-upgrade-.*?\.(sql|pl)$/,
readdir(SQLDIR)));
closedir(SQLDIR);
d319704a Moritz Bunkus
}

faef45c2 Moritz Bunkus
my $db_charset = $main::dbcharset;
$db_charset ||= Common::DEFAULT_CHARSET;

f7057756 Moritz Bunkus
foreach my $db (split(/ /, $form->{dbupdate})) {
d319704a Moritz Bunkus
next unless $form->{$db};

# strip db from dataset
$db =~ s/^db//;
&dbconnect_vars($form, $db);

my $dbh =
DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
or $form->dberror;

8c7e4493 Moritz Bunkus
$dbh->do($form->{dboptions}) if ($form->{dboptions});

d319704a Moritz Bunkus
# check version
$query = qq|SELECT version FROM defaults|;
f7057756 Moritz Bunkus
my ($version) = selectrow_query($form, $dbh, $query);
d319704a Moritz Bunkus
next unless $version;

$version = calc_version($version);

foreach my $upgradescript (@upgradescripts) {
my $a = $upgradescript;
5cf977e5 Moritz Bunkus
$a =~ s/^\Q$form->{dbdriver}\E-upgrade-|\.(sql|pl)$//g;
21c607d3 Moritz Bunkus
my $file_type = $1;
d319704a Moritz Bunkus
my ($mindb, $maxdb) = split /-/, $a;
df9b211e Moritz Bunkus
my $str_maxdb = $maxdb;
d319704a Moritz Bunkus
$mindb = calc_version($mindb);
$maxdb = calc_version($maxdb);

next if ($version >= $maxdb);

# if there is no upgrade script exit
last if ($version < $mindb);

# apply upgrade
d099e800 Moritz Bunkus
$main::lxdebug->message(LXDebug::DEBUG2, "Applying Update $upgradescript");
21c607d3 Moritz Bunkus
if ($file_type eq "sql") {
f7057756 Moritz Bunkus
$self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} .
faef45c2 Moritz Bunkus
"-upgrade/$upgradescript", $str_maxdb, $db_charset);
21c607d3 Moritz Bunkus
} else {
f7057756 Moritz Bunkus
$self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} .
faef45c2 Moritz Bunkus
"-upgrade/$upgradescript", $str_maxdb, $db_charset);
21c607d3 Moritz Bunkus
}
d319704a Moritz Bunkus
$version = $maxdb;

}

$rc = 0;
$dbh->disconnect;

}

$main::lxdebug->leave_sub();

return $rc;
}

4fd8bdbf Moritz Bunkus
sub dbupdate2 {
$main::lxdebug->enter_sub();

my ($self, $form, $controls) = @_;

$form->{sid} = $form->{dbdefault};

my @upgradescripts = ();
my ($query, $sth, $tag);
my $rc = -2;

@upgradescripts = sort_dbupdate_controls($controls);

faef45c2 Moritz Bunkus
my $db_charset = $main::dbcharset;
$db_charset ||= Common::DEFAULT_CHARSET;

4fd8bdbf Moritz Bunkus
foreach my $db (split / /, $form->{dbupdate}) {

next unless $form->{$db};

# strip db from dataset
$db =~ s/^db//;
&dbconnect_vars($form, $db);

my $dbh =
DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
or $form->dberror;

8c7e4493 Moritz Bunkus
$dbh->do($form->{dboptions}) if ($form->{dboptions});

4fd8bdbf Moritz Bunkus
map({ $_->{"applied"} = 0; } @upgradescripts);

0b280f98 Moritz Bunkus
$self->create_schema_info_table($form, $dbh);

f7057756 Moritz Bunkus
$query = qq|SELECT tag FROM schema_info|;
4fd8bdbf Moritz Bunkus
$sth = $dbh->prepare($query);
$sth->execute() || $form->dberror($query);
while (($tag) = $sth->fetchrow_array()) {
$controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
}
$sth->finish();

my $all_applied = 1;
foreach (@upgradescripts) {
if (!$_->{"applied"}) {
$all_applied = 0;
last;
}
}

next if ($all_applied);

foreach my $control (@upgradescripts) {
next if ($control->{"applied"});

a200453a Moritz Bunkus
$control->{description} = SL::Iconv::convert($control->{charset}, $db_charset, $control->{description});
faef45c2 Moritz Bunkus
4fd8bdbf Moritz Bunkus
$control->{"file"} =~ /\.(sql|pl)$/;
my $file_type = $1;

# apply upgrade
d099e800 Moritz Bunkus
$main::lxdebug->message(LXDebug::DEBUG2, "Applying Update $control->{file}");
9aaca433 Moritz Bunkus
print $form->parse_html_template("dbupgrade/upgrade_message2", $control);
4fd8bdbf Moritz Bunkus
if ($file_type eq "sql") {
$self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} .
faef45c2 Moritz Bunkus
"-upgrade2/$control->{file}", $control, $db_charset);
4fd8bdbf Moritz Bunkus
} else {
$self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} .
faef45c2 Moritz Bunkus
"-upgrade2/$control->{file}", $control, $db_charset);
4fd8bdbf Moritz Bunkus
}
}

$rc = 0;
$dbh->disconnect;

}

$main::lxdebug->leave_sub();

return $rc;
}

sub update2_available {
$main::lxdebug->enter_sub();

my ($form, $controls) = @_;

map({ $_->{"applied"} = 0; } values(%{$controls}));

dbconnect_vars($form, $form->{"dbname"});

my $dbh =
DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) ||
$form->dberror;

my ($query, $tag, $sth);

f7057756 Moritz Bunkus
$query = qq|SELECT tag FROM schema_info|;
4fd8bdbf Moritz Bunkus
$sth = $dbh->prepare($query);
d79bc728 Moritz Bunkus
if ($sth->execute()) {
while (($tag) = $sth->fetchrow_array()) {
$controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
}
4fd8bdbf Moritz Bunkus
}
$sth->finish();
$dbh->disconnect();

map({ $main::lxdebug->leave_sub() and return 1 if (!$_->{"applied"}) }
values(%{$controls}));

$main::lxdebug->leave_sub();
return 0;
}

8c7e4493 Moritz Bunkus
sub save_member {
d319704a Moritz Bunkus
$main::lxdebug->enter_sub();

8e6eda05 Moritz Bunkus
my ($self) = @_;
b8da8785 Sven Schöling
my $form = \%main::form;
8e6eda05 Moritz Bunkus
8c7e4493 Moritz Bunkus
# format dbconnect and dboptions string
dbconnect_vars($self, $self->{dbname});
d319704a Moritz Bunkus
8c7e4493 Moritz Bunkus
map { $self->{$_} =~ s/\r//g; } qw(address signature);
d319704a Moritz Bunkus
8c7e4493 Moritz Bunkus
$main::auth->save_user($self->{login}, map { $_, $self->{$_} } config_vars());
d319704a Moritz Bunkus
8c7e4493 Moritz Bunkus
my $dbh = DBI->connect($self->{dbconnect}, $self->{dbuser}, $self->{dbpasswd});
if ($dbh) {
14c1b704 Moritz Bunkus
$self->create_employee_entry($form, $dbh, $self, 1);
8c7e4493 Moritz Bunkus
$dbh->disconnect();
d319704a Moritz Bunkus
}

$main::lxdebug->leave_sub();
}

8c7e4493 Moritz Bunkus
sub create_employee_entry {
d319704a Moritz Bunkus
$main::lxdebug->enter_sub();

14c1b704 Moritz Bunkus
my $self = shift;
my $form = shift;
my $dbh = shift;
my $myconfig = shift;
my $update_existing = shift;
d319704a Moritz Bunkus
c8c960bc Moritz Bunkus
if (!does_table_exist($dbh, 'employee')) {
$main::lxdebug->leave_sub();
return;
}

8c7e4493 Moritz Bunkus
# add login to employee table if it does not exist
# no error check for employee table, ignore if it does not exist
14c1b704 Moritz Bunkus
my ($id) = selectrow_query($form, $dbh, qq|SELECT id FROM employee WHERE login = ?|, $self->{login});
d319704a Moritz Bunkus
14c1b704 Moritz Bunkus
if (!$id) {
b8da8785 Sven Schöling
my $query = qq|INSERT INTO employee (login, name, workphone, role) VALUES (?, ?, ?, ?)|;
8c7e4493 Moritz Bunkus
do_query($form, $dbh, $query, ($self->{login}, $myconfig->{name}, $myconfig->{tel}, "user"));
14c1b704 Moritz Bunkus
} elsif ($update_existing) {
my $query = qq|UPDATE employee SET name = ?, workphone = ?, role = 'user' WHERE id = ?|;
do_query($form, $dbh, $query, $myconfig->{name}, $myconfig->{tel}, $id);
d319704a Moritz Bunkus
}

$main::lxdebug->leave_sub();
}

sub config_vars {
$main::lxdebug->enter_sub();

0dd879bc Moritz Bunkus
my @conf = qw(address admin businessnumber company countrycode
d319704a Moritz Bunkus
currency dateformat dbconnect dbdriver dbhost dbport dboptions
ef5a164c Moritz Bunkus
dbname dbuser dbpasswd email fax name numberformat password
f7057756 Moritz Bunkus
printer role sid signature stylesheet tel templates vclimit angebote
bestellungen rechnungen anfragen lieferantenbestellungen einkaufsrechnungen
taxnumber co_ustid duns menustyle template_format default_media
d707f7ac Moritz Bunkus
default_printer_id copies show_form_details favorites
pdonumber sdonumber);
d319704a Moritz Bunkus
$main::lxdebug->leave_sub();

return @conf;
}

sub error {
$main::lxdebug->enter_sub();

my ($self, $msg) = @_;

98e5f069 Moritz Bunkus
$main::lxdebug->show_backtrace();

d319704a Moritz Bunkus
if ($ENV{HTTP_USER_AGENT}) {
print qq|Content-Type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">

<body bgcolor=ffffff>

<h2><font color=red>Error!</font></h2>
<p><b>$msg</b>|;

}

die "Error: $msg\n";

$main::lxdebug->leave_sub();
}

1;