DbFramework/forms/dbforms.cgi
2021-02-08 00:21:11 +08:00

274 lines
6.9 KiB
Perl
Executable File

#!/usr/local/bin/perl -I../..
=pod
=head1 NAME
dbforms.cgi - Forms interface to DbFramework databases
=head1 SYNOPSIS
http://foo/cgi_bin/dbforms.cgi?db=foo&db_dsn=mysql:database=foo&c_dsn=mysql:database=dbframework_catalog
=head1 DESCRIPTION
B<dbforms.cgi> presents a simple HTML forms interface to any database
configured to work with B<DbFramework>. The database B<must> have the
appropriate catalog entries in the catalog database before it will
work with this script (see L<DbFramework::Catalog/"The Catalog">.)
=head2 Query string arguments
The following arguments are supported in the query string. Mandatory
arguments are shown in B<bold>.
=over 4
=item B<db>
The name of the database.
=item B<db_dsn>
The portion of the DBI DSN after 'DBI:' to be used to connect to the
database e.g. 'mysql:database=foo'.
=item B<c_dsn>
The portion of the DBI DSN after 'DBI:' to be used to connect to the
catalog database e.g. 'mysql:database=dbframework_catalog'.
=item B<host>
The host on which the database is located (default = 'localhost'.)
=back
=head1 SEE ALSO
L<DbFramework::Catalog>.
=head1 AUTHOR
Paul Sharpe E<lt>paul@miraclefish.comE<gt>
=head1 COPYRIGHT
Copyright (c) 1999 Paul Sharpe. England. All rights reserved. This
program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
=cut
use lib '../..';
use DbFramework::Util;
use DbFramework::Persistent;
use DbFramework::DataModel;
use DbFramework::Template;
use DbFramework::Catalog;
use CGI qw/:standard/;
use URI::Escape;
$cgi = new CGI;
$db = $cgi->param('db') || die "No database specified";
$db_dsn = $cgi->param('db_dsn') || die "No database DBI string specified";
$c_dsn = $cgi->param('c_dsn') || die "No catalog DBI string specified";
$host = $cgi->param('host') || undef;
$form = $cgi->param('form') || 'input';
$action = $cgi->param('action') || 'select';
$dsn = "DBI:$db_dsn";
$dsn = "$dsn;host=$host" if $host;
$dm = new DbFramework::DataModel($db,$dsn);
$dm->dbh->{PrintError} = 0; # ePerl chokes on STDERR
$dbh = $dm->dbh; $dbh->{PrintError} = 0;
$dm->init_db_metadata("DBI:$c_dsn");
@tables = @{$dm->collects_table_l};
$class = $table = $cgi->param('table') || $tables[0]->name;
$template = new DbFramework::Template(undef,\@tables);
$template->default($table);
$code = DbFramework::Persistent->make_class($class);
eval $code;
package main;
($t) = $dm->collects_table_h_byname($table);
$catalog = new DbFramework::Catalog("DBI:$c_dsn");
$thing = new $class($t,$dbh,$catalog);
cgi_set_attributes($thing);
# unless ( $form eq 'input' ) {
# $thing->init_pk;
# $thing->table->read_form($form);
# }
# unpack composite column name parameters
for my $param ( $cgi->param ) {
if ( $param =~ /,/ ) {
my @columns = split /,/,$param;
my @values = split /,/,$cgi->param($param);
for ( my $i = 0; $i <= $#columns; $i++ ) {
$cgi->param($columns[$i],$values[$i]);
}
}
}
sub cgi_set_attributes {
my $thing = shift;
my %attributes;
for ( $thing->table->attribute_names ) {
$attributes{$_} = $cgi->param($_) ne '' ? $cgi->param($_) : undef;
}
$thing->attributes_h([%attributes]);
}
sub error {
my $message = shift;
print "<font color=#ff0000><strong>ERROR!</strong><p>$message</font>\n";
}
print $cgi->header;
print <<EOF;
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>$db: $table</title>
</head>
<body>
<table border=1>
<tr>
<td valign=top>
<table>
<tr>
<td valign=top>
<h1>db: $db</h1>
</td>
</tr>
<tr>
<td>
<h4>Tables</h4>
<ul>
EOF
for ( @{$dm->collects_table_l} ) {
my $table = $_->name;
print "<li><a href=",$cgi->url,"?db=$db&driver=$driver&db_dsn=$db_dsn&c_dsn=$c_dsn&host=$host&table=$table>$table</a>\n";
}
print <<EOF;
</ul>
</td>
</tr>
</table>
</td>
<td valign=top>
<table border=0>
<tr>
<td colspan=2 align=middle>
<h1>$table</h1>
</td>
</tr>
<tr>
<td>
EOF
if ( $form eq 'input' ) {
my $self_url = $cgi->self_url;
print "<form method=post action=$self_url>\n";
for ( qw(host driver db db_dsn c_dsn table form) ) {
print "<input type=hidden name=$_ value=",$$_,">\n";
}
my $values_hashref = $thing->table_qualified_attribute_hashref;
print $thing->table->as_html_heading,"\n<tr>\n";
print $template->fill($values_hashref);
for ( 'select','insert' ) {
print "<td><input type=radio name=action value=$_";
print ' checked' if /^$action$/;
print "> $_</td>\n";
}
print <<EOF;
<td><input type=submit value="Submit"></td>
</form>
EOF
}
print <<EOF;
</tr>
</td>
</tr>
EOF
my $action = $cgi->param('action') || '';
SWITCH: {
$action eq 'select' &&
do {
my @names = $thing->table->attribute_names;
my $conditions;
for ( @names ) {
if ( $cgi->param($_) ) {
$conditions .= " AND " if $conditions;
if ( $thing->table->in_foreign_key($thing->table->contains_h_byname($_)) ) {
$conditions .= "$_ = " . $cgi->param($_);
} else {
$conditions .= "$_ " . $cgi->param($_);
}
}
}
my @things = eval { $thing->select($conditions) };
if ( $@ ) {
error($@);
} else {
if ( @things ) {
for my $thing ( @things ) {
my %attributes = %{$thing->attributes_h};
my $url = $cgi->url . "?db=$db&db_dsn=$db_dsn&c_dsn=$c_dsn&host=$host&table=$table&form=$form&action=update";
for ( keys(%attributes) ) {
$url .= uri_escape("&$_=$attributes{$_}");
}
# fill template
my $values_hashref = $thing->attributes_h;
print "<form method=post action=",$cgi->self_url,">\n";
for ( qw(host driver db db_dsn c_dsn table form) ) {
print "<input type=hidden name=$_ value=",$$_,">\n";
}
print $thing->table->is_identified_by->as_hidden_html($values_hashref);
print "<TR>",$template->fill($thing->table_qualified_attribute_hashref),"\n";
print "<td><input type=radio name=action value=update",($action eq 'select') ? ' checked>' : '',"update</td>\n";
print "<td><input type=radio name=action value=delete>",($action eq 'delete') ? ' checked' : '',"delete</td>\n";
print "<td><input type=submit value='Submit'></td></tr></form>\n";
}
} else {
print "<TR><TD><strong>No rows matched your query</strong></TD></TR>\n";
}
}
last SWITCH;
};
$action =~ /^(insert|update|delete)$/ &&
do {
my %attributes;
if ( $action =~ /update/ ) {
# make update condition from current pk
for my $param ( $cgi->param ) {
if ( my($pk_column) = $param =~ /^pk_(\w+)$/ ) {
$attributes{$pk_column} = $cgi->param($param);
}
}
}
cgi_set_attributes($thing);
eval { $thing->$action(\%attributes); };
error($@) if $@;
}
}
$dm->dbh->disconnect;
$dbh->disconnect;
print <<EOF;
</table>
</td>
</tr>
</table>
</body>
</html>
EOF