1 package SL::DBUpgrade2;
8 my ($package, $form, $dbdriver) = @_;
9 my $self = { form => $form, dbdriver => $dbdriver };
10 return bless($self, $package);
13 sub parse_dbupdate_controls {
14 $main::lxdebug->enter_sub();
18 my $form = $self->{form};
19 my $locale = $main::locale;
24 my $path = "sql/" . $self->{dbdriver} . "-upgrade2";
26 foreach my $file_name (<$path/*.sql>, <$path/*.pl>) {
27 next unless (open(IN, $file_name));
29 my $file = $file_name;
39 next unless (/^(--|\#)\s*\@/);
44 my @fields = split(/\s*:\s*/, $_, 2);
45 next unless (scalar(@fields) == 2);
47 if ($fields[0] eq "depends") {
48 push(@{$control->{"depends"}}, split(/\s+/, $fields[1]));
50 $control->{$fields[0]} = $fields[1];
54 next if ($control->{ignore});
56 $control->{charset} ||= Common::DEFAULT_CHARSET;
58 if (!$control->{"tag"}) {
59 _control_error($form, $file_name, $locale->text("Missing 'tag' field.")) ;
62 if ($control->{"tag"} =~ /[^a-zA-Z0-9_\(\)\-]/) {
63 _control_error($form, $file_name, $locale->text("The 'tag' field must only consist of alphanumeric characters or the carachters - _ ( )"))
66 if (defined($all_controls{$control->{"tag"}})) {
67 _control_error($form, $file_name, sprintf($locale->text("More than one control file with the tag '%s' exist."), $control->{"tag"}))
70 if (!$control->{"description"}) {
71 _control_error($form, $file_name, sprintf($locale->text("Missing 'description' field."))) ;
74 $control->{"priority"} *= 1;
75 $control->{"priority"} ||= 1000;
76 $control->{"file"} = $file;
78 delete @{$control}{qw(depth applied)};
80 $all_controls{$control->{"tag"}} = $control;
85 foreach my $control (values(%all_controls)) {
86 foreach my $dependency (@{$control->{"depends"}}) {
87 _control_error($form, $control->{"file"}, sprintf($locale->text("Unknown dependency '%s'."), $dependency)) if (!defined($all_controls{$dependency}));
90 map({ $_->{"loop"} = 0; } values(%all_controls));
91 _check_for_loops($form, $control->{"file"}, \%all_controls, $control->{"tag"});
94 map({ _dbupdate2_calculate_depth(\%all_controls, $_->{"tag"}) }
95 values(%all_controls));
97 $self->{all_controls} = \%all_controls;
99 $main::lxdebug->leave_sub();
101 return \%all_controls;
104 sub _check_for_loops {
105 my ($form, $file_name, $controls, $tag, @path) = @_;
109 my $ctrl = $controls->{$tag};
111 if ($ctrl->{"loop"} == 1) {
113 _control_error($form, $file_name, $main::locale->text("Dependency loop detected:") . " " . join(" -> ", @path))
115 } elsif ($ctrl->{"loop"} == 0) {
118 map({ _check_for_loops($form, $file_name, $controls, $_, @path); } @{ $ctrl->{"depends"} });
124 my ($form, $file_name, $message) = @_;
127 my $locale = $main::locale;
129 $form->error(sprintf($locale->text("Error in database control file '%s': %s"), $file_name, $message));
132 sub _dbupdate2_calculate_depth {
133 $main::lxdebug->enter_sub(2);
135 my ($tree, $tag) = @_;
137 my $node = $tree->{$tag};
139 return $main::lxdebug->leave_sub(2) if (defined($node->{"depth"}));
143 foreach $tag (@{$node->{"depends"}}) {
144 _dbupdate2_calculate_depth($tree, $tag);
145 my $value = $tree->{$tag}->{"depth"};
146 $max_depth = $value if ($value > $max_depth);
149 $node->{"depth"} = $max_depth + 1;
151 $main::lxdebug->leave_sub(2);
154 sub sort_dbupdate_controls {
157 return sort({ $a->{"depth"} != $b->{"depth"} ? $a->{"depth"} <=> $b->{"depth"}
158 : $a->{"priority"} != $b->{"priority"} ? $a->{"priority"} <=> $b->{"priority"}
159 : $a->{"tag"} cmp $b->{"tag"} } values(%{ $self->{all_controls} }));