mirror of
https://github.com/webmin/webmin.git
synced 2026-10-26 05:00:51 +00:00
83 lines
2.8 KiB
Perl
Executable File
83 lines
2.8 KiB
Perl
Executable File
#!/usr/local/bin/perl
|
|
# Adds a column to a table or renames an existing one.
|
|
|
|
use strict;
|
|
use warnings;
|
|
no warnings 'redefine';
|
|
no warnings 'uninitialized';
|
|
our (%text, %in);
|
|
require './sqlite-lib.pl';
|
|
&ReadParse();
|
|
&error_setup($text{'column_err'});
|
|
|
|
# Recheck write access and reload the schema before changing it.
|
|
my $path = &sqlite_database_path($in{'db'});
|
|
&sqlite_can_write($path) || &error($text{'error_readonly'});
|
|
my $dbh = &sqlite_connect($path, 1);
|
|
my $object = &sqlite_object($dbh, $in{'table'});
|
|
$object && $object->{'type'} eq 'table' || &error($text{'table_missing'});
|
|
my $columns = &sqlite_table_columns($dbh, $object->{'name'});
|
|
# Column names are compared without regard to case, as SQLite does.
|
|
my %names = map { lc($_->{'name'}) => 1 } @$columns;
|
|
my $name = $in{'name'};
|
|
$name =~ s/^\s+|\s+$//g;
|
|
|
|
my ($sql, $action, $old_name);
|
|
if ($in{'mode'} eq 'rename') {
|
|
# Renaming keeps everything about the column but its name.
|
|
&sqlite_supports('rename_column') ||
|
|
&error($text{'column_eunsupported'});
|
|
my ($existing) = grep { $_->{'name'} eq $in{'column'} } @$columns;
|
|
$existing || &error($text{'column_emissing'});
|
|
&sqlite_valid_name($name) ||
|
|
&error(&text('create_ecolumn', &html_escape($name)));
|
|
# The same name again is not an error, just nothing to do.
|
|
if ($name eq $existing->{'name'}) {
|
|
$dbh->disconnect();
|
|
&redirect('table.cgi?db='.&urlize($path).'&table='.
|
|
&urlize($object->{'name'}).'&view=structure');
|
|
exit;
|
|
}
|
|
!$names{lc($name)} || lc($name) eq lc($existing->{'name'}) ||
|
|
&error(&text('column_eexists', &html_escape($name)));
|
|
$sql = 'ALTER TABLE '.&sqlite_quote_identifier($object->{'name'}).
|
|
' RENAME COLUMN '.&sqlite_quote_identifier($existing->{'name'}).
|
|
' TO '.&sqlite_quote_identifier($name);
|
|
$action = 'rename';
|
|
$old_name = $existing->{'name'};
|
|
}
|
|
else {
|
|
# Adding validates the definition the way the table form does.
|
|
$sql = eval { &sqlite_add_column_sql($object->{'name'}, {
|
|
'name' => $name,
|
|
'type' => $in{'type'},
|
|
'null' => $in{'null'} ? 1 : 0,
|
|
'default' => $in{'default'} }) };
|
|
# Report a definition problem as a form error.
|
|
if ($@) {
|
|
my $message = $@;
|
|
chomp($message);
|
|
&error($message);
|
|
}
|
|
!$names{lc($name)} ||
|
|
&error(&text('column_eexists', &html_escape($name)));
|
|
$action = 'create';
|
|
}
|
|
|
|
# Run the change.
|
|
eval { $dbh->do($sql); };
|
|
# Pass SQLite's own objection through the normal error page.
|
|
if ($@) {
|
|
my $message = $@;
|
|
$dbh->disconnect();
|
|
&error(&html_escape($message));
|
|
}
|
|
$dbh->disconnect();
|
|
&sqlite_adopt_ownership($path);
|
|
# A rename stores both names so the action log can describe the change.
|
|
&webmin_log($action, 'column', $old_name || $name,
|
|
{ 'db' => $path, 'table' => $object->{'name'},
|
|
$action eq 'rename' ? ( 'name' => $name ) : ( ) });
|
|
&redirect('table.cgi?db='.&urlize($path).'&table='.
|
|
&urlize($object->{'name'}).'&view=structure');
|