Autovivified column data after before_create trigger
[prev]
[thread]
[next]
[Date index for 2004/10/09]
This is a multi-part message in MIME format.
--------------030606020308050606020501
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
As far as I can tell, for every column you set a constraint on, a null entry in the instance data gets created for every column you don't explicitly set.
For example, a table having DDL like this:
CREATE TABLE bar(
bar_id integer unsigned auto_increment primary key,
baz integer unsigned NOT NULL,
quux integer unsigned NOT NULL
);
(note the NOT NULLs) with a class like
package Foo:Bar;
use base 'Foo::Base';
__PACKAGE__->table('foo.bar');
__PACKAGE__->columns(All => qw/bar_id baz quux/);
__PACKAGE__->add_constraint($_ => &is_def) foreach qw/baz quux/;
sub is_def { return defined($_[0]); }
1;
doing this:
my $bar = Foo::Bar->create({baz => 1});
leaves your object data like this after the before_create trigger runs:
bless({baz => 1,
quux => undef}, Foo::Bar);
I expected it to look like this:
bless({baz => 1}, Foo::Bar);
Note that the is_def constraint for `quux` won't get triggered, though
the value violates the constraint. Instead, the error happens at the
database level.
In addition to a very unexpected outcome, now I have to work harder:
-- providing a defined value upfront for every single column
-- parsing and handling a wider variety of possible errors
I've posted about this before. Given the much nicer code base we now
have (thanks guys for all the good work!), my kludgey patch to solve the
problem in a hurry (damn that blind upgrading on production servers) at
least looks a bit cleaner.
IMO, the proble with the included patch is that I shouldn't have to do
this work at all -- oughtn't the constraint checking be run against a local copy of the object? In the limited time that I have, I couldn't
find out how the constraint checking happens in before_create, but if
helps me out bit, I will be more than happyto produce a permanent fix
and a set of tests, because forgetting to check for this problem will
cost me a lot more than the time it takes me to fix it for good.
PS. Is this why the undocumented deflate_before_create trigger exists?
--
Christopher L. Everett
Chief Technology Officer www.medbanner.com
MedBanner, Inc. www.physemp.com
--------------030606020308050606020501
Content-Type: text/x-patch;
name="DBI.pm.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="DBI.pm.patch"
--- DBI.pm.orig 2004-10-08 04:45:24.000000000 -0500
+++ DBI.pm 2004-10-08 03:59:08.000000000 -0500
@@ -578,6 +578,9 @@
my $self = $class->_init($data);
$self->call_trigger('before_create');
+ delete $self->{$_}
+ foreach grep { not exists $self->{__Changed}{$_} and not exists $data->{$_} }
+ $self->all_columns;
$self->call_trigger('deflate_for_create');
$self->_prepopulate_id if $self->_undefined_primary;
--------------030606020308050606020501--
|
(message missing)
|
|
|
Autovivified column data after before_create trigger
Christopher L. Everett 23:15 on 09 Oct 2004
|