Added a Module Config option to show databases and tables using just their names.
---- Changes since 1.410 ----
Improve support for PostgreSQL 8.3 on Ubuntu 8.04.
+---- Changes since 1.440 ----
+Re-wrote the entire user interface to use Webmin's new UI library, for a more consistent and themable look.
+Added a history of previous commands to the Execute SQL page.
&ui_print_footer("", $text{'index_return'});
}
+# Display buttons for adding tables, views and so on
sub show_buttons
{
-# Create table, view and sequence buttons
+print "<table><tr>\n";
if ($access{'tables'}) {
- print "<table width=100%> <tr>\n";
- print "<form action=table_form.cgi>\n";
- print "<input type=hidden name=db value='$in{'db'}'>\n";
- print "<td width=33% nowrap><input type=submit value='$text{'dbase_add'}'>\n";
- print $text{'dbase_fields'},"\n";
- print "<input name=fields size=4 value='4'></td>\n";
- print "</form>\n";
+ # Add a new table
+ print &ui_form_start("table_form.cgi");
+ print &ui_hidden("db", $in{'db'});
+ print "<td>",&ui_submit($text{'dbase_add'})." ".$text{'dbase_fields'}.
+ " ".&ui_textbox("fields", 4, 4),"</td>\n";
+ print &ui_form_end();
+ $form++;
+ # Add a new view
if (&supports_views() && $access{'views'}) {
- print "<form action=edit_view.cgi>\n";
- print "<input type=hidden name=db value='$in{'db'}'>\n";
- print "<input type=hidden name=new value=1>\n";
- print "<td width=33% nowrap align=center><input type=submit value='$text{'dbase_vadd'}'></td>\n";
- print "</form>\n";
+ print &ui_form_start("edit_view.cgi");
+ print &ui_hidden("db", $in{'db'});
+ print &ui_hidden("new", 1);
+ print "<td>",&ui_submit($text{'dbase_vadd'}),"</td>\n";
+ print &ui_form_end();
+ $form++;
}
+ # Add a new sequence
if (&supports_sequences() && $access{'seqs'}) {
- print "<form action=edit_seq.cgi>\n";
- print "<input type=hidden name=db value='$in{'db'}'>\n";
- print "<input type=hidden name=new value=1>\n";
- print "<td width=33% nowrap align=right><input type=submit value='$text{'dbase_sadd'}'></td>\n";
- print "</form>\n";
+ print &ui_form_start("edit_seq.cgi");
+ print &ui_hidden("db", $in{'db'});
+ print &ui_hidden("new", 1);
+ print "<td>",&ui_submit($text{'dbase_sadd'}),"</td>\n";
+ print &ui_form_end();
+ $form++;
}
-
- print "</tr></table>\n";
}
-print "<table width=100%> <tr>\n";
# Drop database button
if ($access{'delete'}) {
- print "<form action=drop_dbase.cgi>\n";
- print "<input type=hidden name=db value='$in{'db'}'>\n";
- print "<td align=left valign=top width=20%><input type=submit ",
- "value='$text{'dbase_drop'}'></td></form>\n";
- }
-else {
- print "<td align=left valign=top width=20%></td>\n";
+ print &ui_form_start("drop_dbase.cgi");
+ print &ui_hidden("db", $in{'db'});
+ print "<td>",&ui_submit($text{'dbase_drop'}),"</td>\n";
+ print &ui_form_end();
+ $form++;
}
# Backup and restore buttons
-if ( &get_postgresql_version() >= 7.2 ) {
+if (&get_postgresql_version() >= 7.2) {
if ($access{'backup'}) {
- print "<form action=backup_form.cgi>\n" ;
- print "<input type=hidden name=db value='$in{'db'}'>\n" ;
- print "<td align=right valign=top width=20%><input type=submit " ,
- "value='$text{'dbase_bkup'}'></td></form>\n" ;
- }
-
+ print &ui_form_start("backup_form.cgi");
+ print &ui_hidden("db", $in{'db'});
+ print "<td>",&ui_submit($text{'dbase_bkup'}),"</td>\n";
+ print &ui_form_end();
+ $form++;
+ }
if ($access{'restore'}) {
- print "<form action=restore_form.cgi>\n" ;
- print "<input type=hidden name=db value='$in{'db'}'>\n" ;
- print "<td align=left valign=top width=20%><input type=submit " ,
- "value='$text{'dbase_rstr'}'></td></form>\n" ;
+ print &ui_form_start("restore_form.cgi");
+ print &ui_hidden("db", $in{'db'});
+ print "<td>",&ui_submit($text{'dbase_rstr'}),"</td>\n";
+ print &ui_form_end();
+ $form++;
+ }
}
-}
-print "<form action=exec_form.cgi>\n";
-print "<input type=hidden name=db value='$in{'db'}'>\n";
-print "<td align=right valign=top width=20%><input type=submit ",
- "value='$text{'dbase_exec'}'></td>\n";
-print "</form>\n";
-print "</tr> </table></form>\n";
+# Execute SQL form
+print &ui_form_start("exec_form.cgi");
+print &ui_hidden("db", $in{'db'});
+print "<td>",&ui_submit($text{'dbase_exec'}),"</td>\n";
+print &ui_form_end();
+$form++;
+
+print "</tr></table>\n";
}
print &ui_hidden("db", $in{'db'}),"\n";
print &ui_hidden("table", $table),"\n";
print &ui_hidden("old", $in{'index'}),"\n";
-print &ui_table_start($text{'index_header1'}, undef, 2, [ "width=30%" ]);
+print &ui_table_start($text{'index_header1'}, undef, 2);
# Index name
print &ui_table_row($text{'index_name'},
print &ui_form_start("save_seq.cgi", "post");
print &ui_hidden("db", $in{'db'}),"\n";
print &ui_hidden("old", $in{'seq'}),"\n";
-print &ui_table_start($text{'seq_header1'}, undef, 2, [ "width=30%" ]);
+print &ui_table_start($text{'seq_header1'}, undef, 2);
# Sequence name
print &ui_table_row($text{'seq_name'},
# Execute some SQL command and display output
require './postgresql-lib.pl';
-&ReadParse();
+&ReadParseMime();
&can_edit_db($in{'db'}) || &error($text{'dbase_ecannot'});
&error_setup($text{'exec_err'});
-$d = &execute_sql_logged($in{'db'}, $in{'cmd'});
-&ui_print_header(undef, $text{'exec_title'}, "");
-print &text('exec_out', "<tt>$in{'cmd'}</tt>"),"<p>\n";
-@data = @{$d->{'data'}};
-if (@data) {
- print &ui_columns_start($d->{'titles'});
- foreach $r (@data) {
- print &ui_columns_row($r);
- }
- print &ui_columns_end();
+if ($in{'clear'}) {
+ # Delete the history file
+ &unlink_file($commands_file.".".$in{'db'});
+ &redirect("exec_form.cgi?db=$in{'db'}");
}
else {
- print "<b>$text{'exec_none'}</b> <p>\n";
+ # Run some SQL
+ $in{'cmd'} = join(" ", split(/[\r\n]+/, $in{'cmd'}));
+ $cmd = $in{'cmd'} ? $in{'cmd'} : $in{'old'};
+ $d = &execute_sql_logged($in{'db'}, $cmd);
+
+ &ui_print_header(undef, $text{'exec_title'}, "");
+ print &text('exec_out', "<tt>".&html_escape($cmd)."</tt>"),"<p>\n";
+ @data = @{$d->{'data'}};
+ if (@data) {
+ print &ui_columns_start($d->{'titles'});
+ foreach $r (@data) {
+ print &ui_columns_row($r);
+ }
+ print &ui_columns_end();
+ }
+ else {
+ print "<b>$text{'exec_none'}</b> <p>\n";
+ }
+
+ # Add to the old commands file
+ open(OLD, "$commands_file.$in{'db'}");
+ while(<OLD>) {
+ s/\r|\n//g;
+ $already++ if ($_ eq $in{'cmd'});
+ }
+ close(OLD);
+ if (!$already && $in{'cmd'} =~ /\S/) {
+ &open_lock_tempfile(OLD, ">>$commands_file.$in{'db'}");
+ &print_tempfile(OLD, "$in{'cmd'}\n");
+ &close_tempfile(OLD);
+ chmod(0700, "$commands_file.$in{'db'}");
+ }
+
+ &webmin_log("exec", undef, $in{'db'}, \%in);
}
-&webmin_log("exec", undef, $in{'db'}, \%in);
-&ui_print_footer("edit_dbase.cgi?db=$in{'db'}", $text{'dbase_return'},
- "", $text{'index_return'});
+&ui_print_footer("exec_form.cgi?db=$in{'db'}", $text{'exec_return'},
+ "edit_dbase.cgi?db=$in{'db'}", $text{'dbase_return'},
+ "", $text{'index_return'});
'file' => $in{'file'} });
unlink($file) if ($in{'mode'});
-&ui_print_footer("edit_dbase.cgi?db=$in{'db'}", $text{'dbase_return'},
- "", $text{'index_return'});
+&ui_print_footer("exec_form.cgi?db=$in{'db'}&mode=file", $text{'exec_return'},
+ "edit_dbase.cgi?db=$in{'db'}", $text{'dbase_return'},
+ "", $text{'index_return'});
&can_edit_db($in{'db'}) || &error($text{'dbase_ecannot'});
&ui_print_header(undef, $text{'exec_title'}, "", "exec_form");
+# Generate tabs for sections
+$prog = "exec_form.cgi?db=".&urlize($in{'db'})."&mode=";
+@tabs = ( [ "exec", $text{'exec_tabexec'}, $prog."exec" ],
+ [ "file", $text{'exec_tabfile'}, $prog."file" ],
+ [ "import", $text{'exec_tabimport'}, $prog."import" ] );
+print &ui_tabs_start(\@tabs, "mode", $in{'mode'} || "exec", 1);
+
+# Get recently run commands
+open(OLD, "$commands_file.$in{'db'}");
+while(<OLD>) {
+ s/\r|\n//g;
+ push(@old, $_);
+ }
+close(OLD);
+
# Form for executing an SQL command
-print "<p>",&text('exec_header', "<tt>$in{'db'}</tt>"),"<p>\n";
-print "<form action=exec.cgi method=post>\n";
-print "<input type=hidden name=db value='$in{'db'}'>\n";
-print "<textarea name=cmd rows=10 cols=70></textarea><br>\n";
-print "<input type=submit value='$text{'exec_exec'}'></form>\n";
+print &ui_tabs_start_tab("mode", "exec");
+print &text('exec_header', "<tt>$in{'db'}</tt>"),"<p>\n";
+print &ui_form_start("exec.cgi", "form-data");
+print &ui_hidden("db", $in{'db'});
+print &ui_textarea("cmd", undef, 10, 70),"<br>\n";
+if (@old) {
+ print $text{'exec_old'}," ",
+ &ui_select("old", undef,
+ [ map { [ $_, &html_escape(length($_) > 80 ?
+ substr($_, 0, 80).".." : $_) ] } @old ]),"\n",
+ &ui_button($text{'exec_edit'}, "movecmd", undef,
+ "onClick='cmd.value = old.options[old.selectedIndex].value'"),
+ " ",&ui_submit($text{'exec_clear'}, "clear"),"<br>\n";
+ }
+print &ui_form_end([ [ undef, $text{'exec_exec'} ] ]);
+print &ui_tabs_end_tab();
# Form for executing commands from a file
-print &ui_hr();
-print "<p>",&text('exec_header2', "<tt>$in{'db'}</tt>"),"<p>\n";
-print "<form action=exec_file.cgi method=post enctype=multipart/form-data>\n";
-print "<input type=hidden name=db value='$in{'db'}'> <table>\n";
-print "<tr> <td><input type=radio name=mode value=0 checked> ",
- "$text{'exec_file'}</td> <td><input name=file size=40> ",
- &file_chooser_button("file", 0, 1),"</td> </tr>\n";
-print "<tr> <td><input type=radio name=mode value=1> ",
- "$text{'exec_upload'}</td> ",
- "<td><input name=upload type=file></td> </tr>\n";
-print "</table> <input type=submit value='$text{'exec_exec'}'></form>\n";
+print &ui_tabs_start_tab("mode", "file");
+print &text('exec_header2', "<tt>$in{'db'}</tt>"),"<p>\n";
+print &ui_form_start("exec_file.cgi", "form-data");
+print &ui_hidden("db", $in{'db'});
+print &ui_radio_table("mode", 0, [
+ [ 0, $text{'exec_file'}, &ui_textbox("file", undef, 50)." ".
+ &file_chooser_button("file", 0, 1) ],
+ [ 1, $text{'exec_upload'}, &ui_upload("upload", 50) ] ]);
+print &ui_form_end([ [ undef, $text{'exec_exec'} ] ]);
+print &ui_tabs_end_tab();
# Form for loading a CSV or tab-separated file
-print &ui_hr();
-print "<p>",&text('exec_header3', "<tt>$in{'db'}</tt>"),"<br>",
+print &ui_tabs_start_tab("mode", "import");
+print &text('exec_header3', "<tt>$in{'db'}</tt>"),"<br>",
$text{'exec_header4'},"<p>\n";
-print "<form action=import.cgi method=post enctype=multipart/form-data>\n";
-print "<input type=hidden name=db value='$in{'db'}'> <table>\n";
-
-print "<tr> <td><input type=radio name=mode value=0 checked> ",
- "$text{'exec_file'}</td> <td><input name=file size=40> ",
- &file_chooser_button("file", 0, 2),"</td> </tr>\n";
+print &ui_form_start("import.cgi", "form-data");
+print &ui_hidden("db", $in{'db'});
+print &ui_table_start(undef, undef, 2);
-print "<tr> <td><input type=radio name=mode value=1> ",
- "$text{'exec_upload'}</td> ",
- "<td><input name=upload type=file></td> </tr>\n";
+# Source for CSV file
+print &ui_table_row($text{'exec_importmode'},
+ &ui_radio_table("mode", 0, [
+ [ 0, $text{'exec_file'}, &ui_textbox("file", undef, 50)." ".
+ &file_chooser_button("file", 0, 1) ],
+ [ 1, $text{'exec_upload'}, &ui_upload("upload", 50) ] ]));
-print "<tr> <td><b>$text{'exec_import'}</b></td>\n";
-print "<td><select name=table>\n";
-foreach $t (&list_tables($in{'db'})) {
- print "<option>$t\n";
- }
-print "</select></td> </tr>\n";
+# Table to import into
+print &ui_table_row($text{'exec_import'},
+ &ui_select("table", undef, [ &list_tables($in{'db'}) ]));
-print "<tr> <td><b>$text{'exec_delete'}</b></td>\n";
-print "<td><input type=radio name=delete value=1> $text{'yes'}\n";
-print "<input type=radio name=delete value=0 checked> $text{'no'}</td> </tr>\n";
+# Delete existing rows?
+print &ui_table_row($text{'exec_delete'},
+ &ui_yesno_radio("delete", 0));
-print "<tr> <td><b>$text{'exec_ignore'}</b></td>\n";
-print "<td><input type=radio name=ignore value=1> $text{'yes'}\n";
-print "<input type=radio name=ignore value=0 checked> $text{'no'}</td> </tr>\n";
+# Ignore dupes?
+print &ui_table_row($text{'exec_ignore'},
+ &ui_yesno_radio("ignore", 0));
-print "<tr> <td><b>$text{'exec_format'}</b></td>\n";
-print "<td>",&ui_radio("format", 2, [ [ 0, $text{'csv_format0'} ],
- [ 1, $text{'csv_format1'} ],
- [ 2, $text{'csv_format2'} ] ]),
- "</td> </tr>\n";
+# CSV format
+print &ui_table_row($text{'exec_format'},
+ &ui_radio("format", 2, [ [ 0, $text{'csv_format0'} ],
+ [ 1, $text{'csv_format1'} ],
+ [ 2, $text{'csv_format2'} ] ]));
-print "</table> <input type=submit value='$text{'exec_exec'}'></form>\n";
+print &ui_table_end();
+print &ui_form_end([ [ undef, $text{'exec_exec'} ] ]);
+print &ui_tabs_end_tab();
+print &ui_tabs_end(1);
&ui_print_footer("edit_dbase.cgi?db=$in{'db'}", $text{'dbase_return'},
"", $text{'index_return'});
failed:
unlink($file) if ($need_unlink);
-&ui_print_footer("edit_dbase.cgi?db=$in{'db'}", $text{'dbase_return'});
+&ui_print_footer("exec_form.cgi?db=$in{'db'}&mode=import", $text{'exec_return'},
+ "edit_dbase.cgi?db=$in{'db'}", $text{'dbase_return'},
+ "", $text{'index_return'});
exec_title=Execute SQL
exec_header=Enter SQL command to execute on database $1 ..
+exec_old=Or select a previous SQL command :
exec_exec=Execute
+exec_clear=Clear History
exec_err=Failed to execute SQL
exec_out=Output from SQL command $1 ..
exec_none=No data returned
exec_import=Table to import data into
exec_header3=Select a text data file to import into PostgreSQL database $1 ..
exec_header4=This file must contain one database record per line, with the fields in either tab separated or CSV format.
+exec_importmode=CSV file source
exec_delete=Delete data in table first?
exec_filename=From filename
exec_ignore=Ignore duplicate rows?
exec_edit=Edit Previous
exec_format=File format
+exec_tabexec=Execute SQL
+exec_tabfile=Run SQL from file
+exec_tabimport=Import text file
+exec_return=execute SQL form
stop_err=Failed to stop database server
stop_epidfile=Failed to open PID file $1
$access{'create'} || &error($text{'newdb_ecannot'});
&ui_print_header(undef, $text{'newdb_title'}, "", "newdb_form");
-print "<form action=newdb.cgi method=post>\n";
-print "<table border>\n";
-print "<tr $tb> <td><b>$text{'newdb_header'}</b></td> </tr>\n";
-print "<tr $cb> <td><table>\n";
+# Start of form block
+print &ui_form_start("newdb.cgi", "post");
+print &ui_table_start($text{'newdb_header'}, undef, 2);
# Database name
-print "<tr> <td><b>$text{'newdb_db'}</b></td>\n";
-print "<td><input name=db size=15></td> </tr>\n";
+print &ui_table_row($text{'newdb_db'},
+ &ui_textbox("db", undef, 40));
if (&get_postgresql_version() >= 7) {
# Owner option
- print "<tr> <td><b>$text{'newdb_user'}</b></td>\n";
- print "<td><input type=radio name=user_def value=1 checked> $text{'default'}\n";
- print "<input type=radio name=user_def value=0>\n";
- print "<select name=user>\n";
$u = &execute_sql($config{'basedb'}, "select usename from pg_shadow");
@users = map { $_->[0] } @{$u->{'data'}};
- foreach $u (@users) {
- print "<option>$u\n";
- }
- print "</select></td> </tr>\n";
+ print &ui_table_row($text{'newdb_user'},
+ &ui_radio("user_def", 1,
+ [ [ 1, $text{'default'} ],
+ [ 0, &ui_select("user", undef, \@users) ] ]));
}
if (&get_postgresql_version() >= 8) {
# Encoding option
- print "<tr> <td><b>$text{'newdb_encoding'}</b></td>\n";
- print "<td>",&ui_opt_textbox("encoding", undef, 20, $text{'default'}),
- "</td> </tr>\n";
+ print &ui_table_row($text{'newdb_encoding'},
+ &ui_opt_textbox("encoding", undef, 20, $text{'default'}));
}
# Path to database file
-print "<tr> <td><b>$text{'newdb_path'}</b></td>\n";
-print "<td>",&ui_opt_textbox("path", undef, 30, $text{'default'}),
- "</td> </tr>\n";
+print &ui_table_row($text{'newdb_path'},
+ &ui_opt_textbox("path", undef, 40, $text{'default'}));
-print "<tr> <td colspan=2 align=right><input type=submit ",
- "value='$text{'create'}'></td> </tr>\n";
-
-print "</table></td></tr></table></form>\n";
+print &ui_table_end();
+print &ui_form_end([ [ undef, $text{'create'} ] ]);
&ui_print_footer("", $text{'index_return'});
'tables' => 1,
'cmds' => 1, );
$max_dbs = $userconfig{'max_dbs'};
+ $commands_file = "$user_module_config_directory/commands";
%displayconfig = %userconfig;
}
else {
$postgres_sameunix = $config{'sameunix'};
}
$max_dbs = $config{'max_dbs'};
+ $commands_file = "$module_config_directory/commands";
%displayconfig = %config;
}
foreach my $hba (split(/\t+/, $config{'hba_conf'})) {
($config{'host'} ? " -h $config{'host'}" : "").
($config{'port'} ? " -h $config{'port'}" : "").
" $db";
+if ($postgres_sameunix && defined(getpwnam($postgres_login))) {
+ $cmd = &command_as_user($postgres_login, 0, $cmd);
+ }
$cmd = &command_with_login($cmd, $user, $pass);
local $out = &backquote_logged("$cmd 2>&1");
return ($out =~ /ERROR/i ? 1 : 0, $out);
&can_edit_db($in{'db'}) || &error($text{'dbase_ecannot'});
&ui_print_header(undef, $text{'table_title2'}, "", "table_form");
-print "<form action=create_table.cgi method=post>\n";
-print "<input type=hidden name=db value='$in{'db'}'>\n";
-print "<table border>\n";
-print "<tr $tb> <td><b>$text{'table_header2'}</b></td> </tr>\n";
-print "<tr $cb> <td><table>\n";
+# Start of form block
+print &ui_form_start("create_table.cgi", "post");
+print &ui_hidden("db", $in{'db'});
+print &ui_table_start($text{'table_header2'}, undef, 2);
-print "<tr> <td><b>$text{'table_name'}</b></td>\n";
-print "<td><input name=name size=30></td> </tr>\n";
+# Table name
+print &ui_table_row($text{'table_name'},
+ &ui_textbox("name", undef, 40));
-print "<tr> <td valign=top><b>$text{'table_initial'}</b></td>\n";
-print "<td><table border>\n";
-print "<tr $tb> <td><b>$text{'field_name'}</b></td> ",
- "<td><b>$text{'field_type'}</b></td> ",
- "<td><b>$text{'field_size'}</b></td> ",
- "<td><b>$text{'table_opts'}</b></td> </tr>\n";
+# Initial fields
@type_list = &list_types();
for($i=0; $i<(int($in{'fields'}) || 4); $i++) {
- print "<tr $cb>\n";
- print "<td><input name=field_$i size=20></td>\n";
- print "<td><select name=type_$i>\n";
- print "<option selected>\n";
- foreach $t (@type_list) {
- print "<option>$t\n";
- }
- print "</select></td>\n";
- print "<td><input name=size_$i size=10></td> <td>\n";
- print "<input name=arr_$i type=checkbox value=1> $text{'table_arr'}\n";
- print "<input name=null_$i type=checkbox value=1 checked> $text{'field_null'}\n";
- print "<input name=key_$i type=checkbox value=1> $text{'field_key'}\n";
- print "<input name=uniq_$i type=checkbox value=1> $text{'field_uniq'}\n";
- print "</td> </tr>\n";
+ push(@table, [
+ &ui_textbox("field_$i", undef, 30),
+ &ui_select("type_$i", undef,
+ [ [ undef, ' ' ], @type_list ]),
+ &ui_textbox("size_$i", undef, 10),
+ &ui_checkbox("arr_$i", 1, $text{'table_arr'}, 0)." ".
+ &ui_checkbox("null_$i", 1, $text{'field_null'}, 1)." ".
+ &ui_checkbox("key_$i", 1, $text{'field_key'}, 0)." ".
+ &ui_checkbox("uniq_$i", 1, $text{'field_uniq'}, 0),
+ ]);
}
-print "</table></td> </tr>\n";
+print &ui_table_row($text{'table_initial'},
+ &ui_columns_table([ $text{'field_name'}, $text{'field_type'},
+ $text{'field_size'}, $text{'table_opts'} ],
+ undef, \@table));
-print "<tr> <td colspan=2 align=right><input type=submit ",
- "value='$text{'create'}'></td> </tr>\n";
-
-print "</table></td></tr></table></form>\n";
+print &ui_table_end();
+print &ui_form_end([ [ undef, $text{'create'} ] ]);
&ui_print_footer("edit_dbase.cgi?db=$in{'db'}", $text{'dbase_return'});