Projekt

Allgemein

Profil

Herunterladen (3,94 KB) Statistiken
| Zweig: | Markierung: | Revision:
4fd8bdbf Moritz Bunkus
package SL::DBUpgrade2;

faef45c2 Moritz Bunkus
use SL::Common;

4fd8bdbf Moritz Bunkus
require Exporter;
@ISA = qw(Exporter);

@EXPORT = qw(parse_dbupdate_controls sort_dbupdate_controls);

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

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

my $locale = $main::locale;

local *IN;
my %all_controls;

my $path = "sql/${dbdriver}-upgrade2";

foreach my $file_name (<$path/*.sql>, <$path/*.pl>) {
next unless (open(IN, $file_name));

my $file = $file_name;
$file =~ s|.*/||;

my $control = {
"priority" => 1000,
53c7990b Moritz Bunkus
"depends" => [],
4fd8bdbf Moritz Bunkus
};

while (<IN>) {
chomp();
next unless (/^(--|\#)\s*\@/);
s/^(--|\#)\s*\@//;
s/\s*$//;
next if ($_ eq "");

my @fields = split(/\s*:\s*/, $_, 2);
next unless (scalar(@fields) == 2);

if ($fields[0] eq "depends") {
push(@{$control->{"depends"}}, split(/\s+/, $fields[1]));
} else {
$control->{$fields[0]} = $fields[1];
}
}

faef45c2 Moritz Bunkus
$control->{charset} ||= Common::DEFAULT_CHARSET;

53c7990b Moritz Bunkus
if (!$control->{"tag"}) {
_control_error($form, $file_name, $locale->text("Missing 'tag' field.")) ;
}
4fd8bdbf Moritz Bunkus
53c7990b Moritz Bunkus
if ($control->{"tag"} =~ /[^a-zA-Z0-9_\(\)\-]/) {
_control_error($form, $file_name, $locale->text("The 'tag' field must only consist of alphanumeric characters or the carachters - _ ( )"))
}
4fd8bdbf Moritz Bunkus
53c7990b Moritz Bunkus
if (defined($all_controls{$control->{"tag"}})) {
_control_error($form, $file_name, sprintf($locale->text("More than one control file with the tag '%s' exist."), $control->{"tag"}))
}
4fd8bdbf Moritz Bunkus
53c7990b Moritz Bunkus
if (!$control->{"description"}) {
_control_error($form, $file_name, sprintf($locale->text("Missing 'description' field."))) ;
}
4fd8bdbf Moritz Bunkus
53c7990b Moritz Bunkus
$control->{"priority"} *= 1;
$control->{"priority"} ||= 1000;
$control->{"file"} = $file;
4fd8bdbf Moritz Bunkus
53c7990b Moritz Bunkus
delete @{$control}{qw(depth applied)};
4fd8bdbf Moritz Bunkus
$all_controls{$control->{"tag"}} = $control;

close(IN);
}

foreach my $control (values(%all_controls)) {
foreach my $dependency (@{$control->{"depends"}}) {
53c7990b Moritz Bunkus
_control_error($form, $control->{"file"}, sprintf($locale->text("Unknown dependency '%s'."), $dependency)) if (!defined($all_controls{$dependency}));
4fd8bdbf Moritz Bunkus
}

map({ $_->{"loop"} = 0; } values(%all_controls));
53c7990b Moritz Bunkus
_check_for_loops($form, $control->{"file"}, \%all_controls, $control->{"tag"});
4fd8bdbf Moritz Bunkus
}

map({ _dbupdate2_calculate_depth(\%all_controls, $_->{"tag"}) }
values(%all_controls));

$main::lxdebug->leave_sub();

return \%all_controls;
}

sub _check_for_loops {
my ($form, $file_name, $controls, $tag, @path) = @_;

push(@path, $tag);

ad876674 Moritz Bunkus
my $ctrl = $controls->{$tag};

if ($ctrl->{"loop"} == 1) {
# Not done yet.
53c7990b Moritz Bunkus
_control_error($form, $file_name, $main::locale->text("Dependency loop detected:") . " " . join(" -> ", @path))

ad876674 Moritz Bunkus
} elsif ($ctrl->{"loop"} == 0) {
# Not checked yet.
$ctrl->{"loop"} = 1;
53c7990b Moritz Bunkus
map({ _check_for_loops($form, $file_name, $controls, $_, @path); } @{ $ctrl->{"depends"} });
ad876674 Moritz Bunkus
$ctrl->{"loop"} = 2;
}
4fd8bdbf Moritz Bunkus
}

sub _control_error {
my ($form, $file_name, $message) = @_;

0cfb13d0 Udo Spallek
$form = $main::form;
4fd8bdbf Moritz Bunkus
my $locale = $main::locale;

53c7990b Moritz Bunkus
$form->error(sprintf($locale->text("Error in database control file '%s': %s"), $file_name, $message));
4fd8bdbf Moritz Bunkus
}

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

my ($tree, $tag) = @_;

my $node = $tree->{$tag};

return $main::lxdebug->leave_sub() if (defined($node->{"depth"}));

my $max_depth = 0;

foreach $tag (@{$node->{"depends"}}) {
_dbupdate2_calculate_depth($tree, $tag);
my $value = $tree->{$tag}->{"depth"};
$max_depth = $value if ($value > $max_depth);
}

$node->{"depth"} = $max_depth + 1;

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

sub sort_dbupdate_controls {
53c7990b Moritz Bunkus
return sort({ $a->{"depth"} != $b->{"depth"} ? $a->{"depth"} <=> $b->{"depth"}
: $a->{"priority"} != $b->{"priority"} ? $a->{"priority"} <=> $b->{"priority"}
: $a->{"tag"} cmp $b->{"tag"} } values(%{$_[0]}));
4fd8bdbf Moritz Bunkus
}

1;