[prev] [thread] [next] [Date index for 2005/11/16]
This is a multi-part message in MIME format.
--------------070301020707050406080208
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Hi everyone!
So I have written a small database application using Class::DBI and I
have a table of Links and a table of LinkCategories. Each Link has a
LinkCategory and thus each LinkCategory has many Links. I have written
an admin interface so I can create new Links and LinkCategories as I
wish. All works as expected on my PC.
However, I have now uploaded the code to my laptop and it does not work
on there! My laptop is using the latest Class::DBI version available on
CPAN - my PC is using version 0.95!! If I replace the DBI.pm file on my
laptop with the one on my PC everything works fine!
So that's the background - here is the error message:
Can't use an undefined value as a HASH reference at
C:/Perl/site/lib/Class/DBI/Relationship/HasMany.pm line 51. Compilation
failed in require at c:\httpd\bowdonrufc\cgi-bin/BowdonRUFC/Admin.pm
line 104.
Anyone got an idea what could be going wrong? Please find my Link.pm,
LinkCategory.pm and Admin.pm attached if that is of any help!?
Thanks
Jay
--
bingo, bango, bosh...
--------------070301020707050406080208
Content-Type: text/plain;
name="Admin.pm"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="Admin.pm"
#
# Admin.pm
# This file may not be reproduced without written permission
#
package BowdonRUFC::Admin;
use CGI::Builder
qw| CGI::Builder::Session
CGI::Builder::Auth
CGI::Builder::Magic
BowdonRUFC
|;
use strict;
use Data::Dumper;
use HTML::Entities;
sub OH_init
{ my $s = shift;
$s->require_group = [ 'ADMIN' ];
}
sub PH_index
{ my $s = shift;
$s->title = "Welcome To Bowdon R.U.F.C (Admin Interface)";
$s->content = <<_END_HTML_;
Please select from the following options:<br>
<ul>
<li><b>Pages</b>
[ <a href="/cgi-bin/admin.cgi?p=create&m=Page">Create</a> ]
[ <a href="/cgi-bin/admin.cgi?p=modify&m=Page">Modify</a> ]
[ <a href="/cgi-bin/admin.cgi?p=delete&m=Page">Delete</a> ]
</li>
<br>
<li><b>Links</b>
[ <a href="/cgi-bin/admin.cgi?p=create&m=Link">Create</a> ]
[ <a href="/cgi-bin/admin.cgi?p=modify&m=Link">Modify</a> ]
[ <a href="/cgi-bin/admin.cgi?p=delete&m=Link">Delete</a> ]
</li>
<li><b>Link Categories</b>
[ <a href="/cgi-bin/admin.cgi?p=create&m=LinkCategory">Create</a> ]
[ <a href="/cgi-bin/admin.cgi?p=modify&m=LinkCategory">Modify</a> ]
[ <a href="/cgi-bin/admin.cgi?p=delete&m=LinkCategory">Delete</a> ]
</li>
<br>
<li><b>Contacts</b>
[ <a href="/cgi-bin/admin.cgi?p=create&m=Contact">Create</a> ]
[ <a href="/cgi-bin/admin.cgi?p=modify&m=Contact">Modify</a> ]
[ <a href="/cgi-bin/admin.cgi?p=delete&m=Contact">Delete</a> ]
</li>
<br>
<li><b>News</b>
[ <a href="/cgi-bin/admin.cgi?p=create&m=News">Create</a> ]
[ <a href="/cgi-bin/admin.cgi?p=modify&m=News">Modify</a> ]
[ <a href="/cgi-bin/admin.cgi?p=delete&m=News">Delete</a> ]
</li>
<li><b>News Categories</b>
[ <a href="/cgi-bin/admin.cgi?p=create&m=NewsCategory">Create</a> ]
[ <a href="/cgi-bin/admin.cgi?p=modify&m=NewsCategory">Modify</a> ]
[ <a href="/cgi-bin/admin.cgi?p=delete&m=NewsCategory">Delete</a> ]
</li>
<br>
<li><b>Clubs</b>
[ <a href="/cgi-bin/admin.cgi?p=create&m=Club">Create</a> ]
[ <a href="/cgi-bin/admin.cgi?p=modify&m=Club">Modify</a> ]
[ <a href="/cgi-bin/admin.cgi?p=delete&m=Club">Delete</a> ]
</li>
<li><b>Teams</b>
[ <a href="/cgi-bin/admin.cgi?p=create&m=Team">Create</a> ]
[ <a href="/cgi-bin/admin.cgi?p=modify&m=Team">Modify</a> ]
[ <a href="/cgi-bin/admin.cgi?p=delete&m=Team">Delete</a> ]
</li>
<br>
<li><b>Competitions</b>
[ <a href="/cgi-bin/admin.cgi?p=create&m=Competition">Create</a> ]
[ <a href="/cgi-bin/admin.cgi?p=modify&m=Competition">Modify</a> ]
[ <a href="/cgi-bin/admin.cgi?p=delete&m=Competition">Delete</a> ]
</li>
<li><b>Fixtures</b>
[ <a href="/cgi-bin/admin.cgi?p=create&m=Fixture">Create</a> ]
[ <a href="/cgi-bin/admin.cgi?p=modify&m=Fixture">Modify</a> ]
[ <a href="/cgi-bin/admin.cgi?p=delete&m=Fixture">Delete</a> ]
</li>
</ul>
_END_HTML_
}
sub SH_create
{ my $s = shift;
return $s->switch_to('index') unless $s->cgi->param('m');
}
sub PH_create
{ my $s = shift;
my $m = $s->cgi->param('m');
$s->title = "Create A $m";
my $module = "BowdonRUFC::$m";
unless (eval { require File::Spec->catfile(split /::/, "$module.pm") })
{ $s->errstr = "The specified module ($module) does not exist.";
$s->debug .= $@;
return $s->switch_to('error');
}
my $columns = eval ( '$' . $module . '::columns' );
unless ($columns)
{ $s->errstr = "Unable to obtain column list for the specified module ($module).";
return $s->switch_to('error');
}
if (defined $s->cgi->param('do_create') and
&do_create($s, $m, $module))
{ my $url = $s->cgi->url . "?m=$m&" . $s->cgi_page_param . "=" . $s->cgi->param($s->cgi_page_param);
return $s->content = "Success! Your $m was successfully created.<p>Click <a href='$url'>here</a> to create another $m";
} else
{ return $s->content = &show_form($s, $m, $module);
}
}
sub PH_select
{ my $s = shift;
my ($m, $module) = @_;
my @options;
foreach my $mi (sort $module->retrieve_all)
{ my $id = $mi->id;
push @options, "<option value='$id'>$mi</option>";
}
unless (@options)
{ $s->errstr = "No $m available for selection";
return $s->switch_to('error');
}
my $start_form = $s->cgi->start_multipart_form();
my $end_form = $s->cgi->end_form();
my $page_param = $s->cgi->hidden($s->cgi_page_param);
my $m_param = $s->cgi->hidden('m');
my $primary_column = $module->primary_column;
$s->content .= <<_END_HTML_;
$start_form
$page_param
$m_param
<div id="form">
<div class="wrapper" style="padding: 10px;">
<h3>Select $m</h3>
<div style="padding-bottom: 30px;">
<div class="clearfix"><span class="field">$m:</span><select name="select_$primary_column" class="flat" style="float: left;">@options</select><span style="padding-left: 10px;"><b>(required)</b></span></div>
<div id="submit"><span class="field">Submit:</span><input type="submit" value="Select $m" class="button"></div>
</div>
</div>
</div>
_END_HTML_
}
sub SH_modify
{ my $s = shift;
return $s->switch_to('index') unless $s->cgi->param('m');
}
sub PH_modify
{ my $s = shift;
my $m = $s->cgi->param('m');
$s->title = "Modify An Existing $m";
my $module = "BowdonRUFC::$m";
unless (eval { require File::Spec->catfile(split /::/, "$module.pm") })
{ $s->errstr = "The specified module ($module) does not exist.";
$s->debug .= $@;
return $s->switch_to('error');
}
my $select_id = $s->cgi->param('select_' . $module->primary_column);
unless (defined $select_id)
{ return $s->switch_to('select', $m, $module);
}
my $obj = $module->retrieve($select_id);
unless (defined $obj)
{ $s->errstr = "The selected $m does not exist";
return $s->switch_to('error');
}
if (defined $s->cgi->param('do_modify') and
&do_modify($s, $m, $module, $obj))
{ my $url = $s->cgi->url . "?m=$m&" . $s->cgi_page_param . "=" . $s->cgi->param($s->cgi_page_param);
return $s->content = "Success! Your $m was successfully modified.<p>Click <a href='$url'>here</a> to modify another $m";
} else
{ return $s->content = &show_form($s, $m, $module, $obj);
}
}
sub PH_delete
{ my $s = shift;
my $m = $s->cgi->param('m');
$s->title = "Delete An Existing $m";
my $module = "BowdonRUFC::$m";
unless (eval { require File::Spec->catfile(split /::/, "$module.pm") })
{ $s->errstr = "The specified module ($module) does not exist.";
$s->debug .= $@;
return $s->switch_to('error');
}
my $select_id = $s->cgi->param('select_' . $module->primary_column);
unless (defined $select_id)
{ return $s->switch_to('select', $m, $module);
}
my $obj = $module->retrieve($select_id);
unless (defined $obj)
{ $s->errstr = "The selected $m does not exist";
return $s->switch_to('error');
}
if (defined $s->cgi->param('do_delete') and
&do_delete($s, $m, $module, $obj))
{ my $url = $s->cgi->url . "?m=$m&" . $s->cgi_page_param . "=" . $s->cgi->param($s->cgi_page_param);
return $s->content = "Success! Your $m was successfully deleted.<p>Click <a href='$url'>here</a> to delete another $m";
} else
{ return $s->content = &show_delete_form($s, $m, $module, $obj);
}
}
#
# utility functions
#
sub do_create
{ my $s = shift;
my ($m, $module) = @_;
my $columns = eval ( '$' . $module . '::columns' );
unless ($columns)
{ $s->errstr = "Unable to obtain column list for the specified module ($module).";
return $s->switch_to('error');
}
my ($require, $obj);
foreach my $c (@$columns) # check required values are provided and encode HTML where necessary
{ if ($c->{REQUIRED} and
$s->cgi->param($c->{NAME}) eq '')
{ push @$require, "Required field $c->{NAME} missing";
next;
}
$obj->{$c->{NAME}} = $c->{NOENCODE} ? $s->cgi->param($c->{NAME})
: &HTML::Entities::encode_entities($s->cgi->param($c->{NAME}));
}
if (defined $require)
{ $BowdonRUFC::errstr = &handle_error($s, $require);
return undef;
}
unless (eval { $module->create($obj) })
{ $BowdonRUFC::errstr = &handle_error($s, $@);
return undef;
}
return 1;
}
sub do_modify
{ my $s = shift;
my ($m, $module, $obj) = @_;
my $columns = eval ( '$' . $module . '::columns' );
unless ($columns)
{ $s->errstr = "Unable to obtain column list for the specified module ($module).";
return $s->switch_to('error');
}
my ($require, $new);
foreach my $c (@$columns) # check required values are provided and encode HTML where necessary
{ if ($c->{REQUIRED} and
$s->cgi->param($c->{NAME}) eq '')
{ push @$require, "Required field $c->{NAME} missing";
next;
}
$new->{$c->{NAME}} = $c->{NOENCODE} ? $s->cgi->param($c->{NAME})
: &HTML::Entities::encode_entities($s->cgi->param($c->{NAME}));
}
if (defined $require)
{ $BowdonRUFC::errstr = &handle_error($s, $require);
return undef;
}
my $command = '$obj->update';
if ($new->{$module->primary_column} ne $obj->id)
{ $command = '$module->move($obj, $new) and $obj->delete';
} else
{ foreach my $k (keys %$new)
{ unless (eval { $obj->$k($new->{$k}) })
{ $BowdonRUFC::errstr = &handle_error($s, $@);
return undef;
}
}
}
unless (eval($command))
{ $BowdonRUFC::errstr = &handle_error($s, $@);
return undef;
}
return 1;
}
sub do_delete
{ my $s = shift;
my ($m, $module, $obj) = @_;
my $columns = eval ( '$' . $module . '::columns' );
unless ($columns)
{ $s->errstr = "Unable to obtain column list for the specified module ($module).";
return $s->switch_to('error');
}
unless (eval { $obj->delete })
{ $BowdonRUFC::errstr = "An error occurred while deleting your $m";
return undef;
}
return 1;
}
sub show_form
{ my $s = shift;
my ($m, $module, $obj) = @_;
my $columns = eval ( '$' . $module . '::columns' );
unless ($columns)
{ $s->errstr = "Unable to obtain column list for the specified module ($module).";
return $s->switch_to('error');
}
my $start_form = $s->cgi->start_multipart_form();
my $end_form = $s->cgi->end_form();
my $page_param = $s->cgi->hidden($s->cgi_page_param);
my $m_param = $s->cgi->hidden('m');
my $action = $obj ? 'Modify' : 'Create';
my $do_param = $s->cgi->hidden('do_' . lc $action, 'true');
my $primary_column = $module->primary_column;
my $select_id_param = $s->cgi->hidden("select_$primary_column");
$s->content .= "<span class='error'>$BowdonRUFC::errstr</span><br><br>" if (defined $BowdonRUFC::errstr);
$s->content .= <<_END_HTML_;
$start_form
$page_param
$m_param
$do_param
$select_id_param
<div id="form">
<div class="wrapper" style="padding: 10px;">
<h3>$m Details</h3>
<div style="padding-bottom: 30px;">
_END_HTML_
my $param;
foreach my $c (@$columns)
{ my $name = $c->{NAME};
if (defined $s->cgi->param($name))
{ $param->{$name} = $s->cgi->param($name);
} elsif (defined $obj and $obj->can($name))
{ $param->{$name} = $obj->$name;
}
}
foreach my $c (@$columns)
{ next if ($c->{REQUIRE_GROUP} and
not $s->auth->require_group($c->{REQUIRE_GROUP})); # some fields are only available to priviliged users
my $name = $s->functions->format_column($c->{NAME});
my $value = $param->{$c->{NAME}};
my $required = '<b>(required)</b>' if $c->{REQUIRED};
if ($c->{TYPE} eq 'GENERATE') # generate id and pass as hidden field
{ $value = ($value or $s->functions->generate_id);
$s->content .= <<_END_HTML_;
<input type="hidden" name="$c->{NAME}" value="$value">
_END_HTML_
} elsif ($c->{TYPE} eq 'DATE') # create date field
{ $value = ($value or $s->functions->parse_date);
$s->content .= <<_END_HTML_;
<div class="clearfix"><span class="field">$name:</span><input type="TEXT" name="$c->{NAME}" value="$value" class="flat" style="float: left;"><span style="padding-left: 10px;">$required</span></div>
_END_HTML_
} elsif ($c->{TYPE} eq 'TEXT') # create simple plain text field
{ $s->content .= <<_END_HTML_;
<div class="clearfix"><span class="field">$name:</span><input type="TEXT" name="$c->{NAME}" value="$value" class="flat" style="float: left;"><span style="padding-left: 10px;">$required</span></div>
_END_HTML_
} elsif ($c->{TYPE} eq 'TEXTAREA') # create simple textarea field
{ $s->content .= <<_END_HTML_;
<div class="clearfix"><span class="field">$name:</span><textarea name="$c->{NAME}" class="flat" style="float: left">$value</textarea><span style="padding-left: 10px;">$required</span></div>
_END_HTML_
} elsif ($c->{TYPE} eq 'LIST') # load the required module and query values for dropdown list
{ unless (eval { require File::Spec->catfile(split /::/, "$c->{MODULE}.pm") })
{ $s->errstr = "The specified module ($c->{MODULE}) does not exist.";
$s->debug .= $@;
return $s->switch_to('error');
}
my $id = $obj ? $value->id : $value;
my $selected = { $id => "selected='selected'" };
my @options = ( "<option value=''>--- Select An Option ---</option>" );
foreach my $lc ($c->{MODULE}->retrieve_all)
{ my $id = $lc->id;
push @options, "<option value='$id' $selected->{$id}>$lc</option>";
}
$s->content .= <<_END_HTML_;
<div class="clearfix"><span class="field">$name:</span><select name="$c->{NAME}" class="flat" style="float: left;">@options</select><span style="padding-left: 10px;">$required</span></div>
_END_HTML_
}
}
$s->content .= <<_END_HTML_;
</div>
<h3>$action $m</h3>
<div>
<div id="submit"><span class="field">Submit:</span><input type="submit" value="$action $m" class="button"></div>
</div>
</div>
</div>
$end_form
_END_HTML_
}
sub show_delete_form
{ my $s = shift;
my ($m, $module, $obj) = @_;
my $columns = eval ( '$' . $module . '::columns' );
unless ($columns)
{ $s->errstr = "Unable to obtain column list for the specified module ($module).";
return $s->switch_to('error');
}
my $start_form = $s->cgi->start_multipart_form();
my $end_form = $s->cgi->end_form();
my $page_param = $s->cgi->hidden($s->cgi_page_param);
my $m_param = $s->cgi->hidden('m');
my $do_param = $s->cgi->hidden('do_delete', 'true');
my $primary_column = $module->primary_column;
my $select_id_param = $s->cgi->hidden("select_$primary_column");
$s->content .= "<span class='error'>$BowdonRUFC::errstr</span><br><br>" if (defined $BowdonRUFC::errstr);
$s->content .= <<_END_HTML_;
$start_form
$page_param
$m_param
$do_param
$select_id_param
<div id="form">
<div class="wrapper" style="padding: 10px;">
<h3>$m Details</h3>
<div style="padding-bottom: 30px;">
_END_HTML_
foreach my $c (@$columns)
{ next if ($c->{REQUIRE_GROUP} and
not $s->auth->require_group($c->{REQUIRE_GROUP})); # some fields are only available to priviliged users
my $name = $c->{NAME};
my $title = $s->functions->format_column($name);
my $value = $obj->$name;
$s->content .= <<_END_HTML_;
<div class="clearfix"><span class="field">$title:</span><span style="float: left; display: block;">$value</span></div>
_END_HTML_
}
$s->content .= <<_END_HTML_;
</div>
<h3>Delete $m</h3>
<div>
<div id="submit"><span class="field">Submit:</span><input type="submit" value="Delete $m" class="button"></div>
</div>
</div>
</div>
$end_form
_END_HTML_
}
#
# error handling
#
sub handle_error
{ my ($s, $e) = @_;
my $errstr = 'The following error(s) were encountered:';
if (ref $e eq 'HASH')
{ my $method = $e->{INFO}->{method};
if ($method eq 'validate_column_values')
{ my $err = $e->{INFO}->{data};
foreach my $k (keys %$err)
{ $errstr .= "<p>Invalid value provided for $k field</p>";
}
} elsif ($e->{INFO}->{err} =~ /duplicate/i)
{ $errstr .= "<p>Duplicate entry - please provide an alternative ID</p>";
}
} elsif (ref $e eq 'ARRAY')
{ $errstr .= join('<br>', @$e);
}
$s->debug .= '<pre>' . Dumper($e) . '</pre>';
return $errstr;
}
1;
--------------070301020707050406080208
Content-Type: text/plain;
name="Link.pm"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="Link.pm"
#
# BowdonRUFC::Link.pm
#
package BowdonRUFC::Link;
use base BowdonRUFC::DBI;
$BowdonRUFC::Link::columns = [ { NAME => 'link_id',
REQUIRED => 1,
TYPE => 'GENERATE',
},
{ NAME => 'title',
REQUIRED => 1,
TYPE => 'TEXT',
},
{ NAME => 'description',
TYPE => 'TEXTAREA',
},
{ NAME => 'url',
REQUIRED => 1,
TYPE => 'TEXT',
},
{ NAME => 'link_category',
REQUIRED => 1,
TYPE => 'LIST',
MODULE => 'BowdonRUFC::LinkCategory',
} ];
__PACKAGE__->table("Links");
__PACKAGE__->columns(All => map { $_->{NAME} } @$BowdonRUFC::Link::columns);
__PACKAGE__->columns(Stringify => qw/title/);
__PACKAGE__->constrain_column(url => UntaintPatched => "url");
__PACKAGE__->has_a(link_category => 'BowdonRUFC::LinkCategory' );
1;
--------------070301020707050406080208
Content-Type: text/plain;
name="LinkCategory.pm"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="LinkCategory.pm"
#
# BowdonRUFC::LinkCategory.pm
#
package BowdonRUFC::LinkCategory;
use base BowdonRUFC::DBI;
$BowdonRUFC::LinkCategory::columns = [ { NAME => 'link_category_id',
REQUIRED => 1,
TYPE => 'GENERATE',
},
{ NAME => 'title',
REQUIRED => 1,
TYPE => 'TEXT',
},
{ NAME => 'description',
TYPE => 'TEXTAREA',
} ];
__PACKAGE__->table("LinkCategories");
__PACKAGE__->columns(All => map { $_->{NAME} } @$BowdonRUFC::LinkCategory::columns);
__PACKAGE__->columns(Stringify => qw/title/);
__PACKAGE__->has_many(links => 'BowdonRUFC::Link');
1;
--------------070301020707050406080208
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
ClassDBI mailing list
ClassDBI@xxxxx.xxxxxxxxxxxxxxxx.xxx
http://lists.digitalcraftsmen.net/mailman/listinfo/classdbi
--------------070301020707050406080208--
|
[CDBI] Class::DBI Has Many Error
|
|
Re: [CDBI] Class::DBI Has Many Error
|
|
Re: [CDBI] Class::DBI Has Many Error
|
|
Re: [CDBI] Class::DBI Has Many Error
|
Generated at 21:49 on 21 Nov 2005 by mariachi v0.52