This is one of those issues you hope you don't encounter more than once a year...
Try this:
Setup a database with the following schema:
create table foo (
test1 int not null auto_increment,
test2 int null,
primary key (test1)
);
Setup a CDBI class like this:
package Foo;
use base 'Class::DBI';
__PACKAGE__->columns(
All => qw/test1 test2/
);
__PACKAGE__->add_trigger(before_create => \&trigger_code);
sub trigger_code {
my $self = shift;
$self->test2('123') unless $self->test2;
}
i.e. we're setting a default value.
Now write a script to insert a row:
Foo->connection('dbi:mysql:dbname=testdb','root','');
Foo->create({});
If all went according to plan, you should have a row inserted into your DB with the 'test2' column set to the default value.
Here comes the weird part. Add the line
use Test::MockObject at the top of your script. (You don't actually have to use the module in any way). If you're anything like me, you'll get the error:
Use of uninitialized value in split at /usr/local/share/perl/5.8.4/UNI
+VERSAL/can.pm line 51.
Called UNIVERSAL::can() as a function, not a method at /usr/local/shar
+e/perl/5.8.4/Class/DBI.pm line 265
Can't call method "can" on an undefined value at /usr/local/share/perl
+/5.8.4/UNIVERSAL/can.pm line 40.
Extremely strange.... and the sort of thing you can easily spend an afternoon chasing (guess who just did this...)
Now try one of the following:
- Hardcode the primary key value when you 'create' (i.e. set 'test1' to something)
- Change the trigger function by removing the unless $self->test2; part
- Or, obviously, remove the use Test::MockObject line.
Anyone of these should solve the problem...
Hmm... anyone have any ideas why this might be the case? (Note, I haven't tried this on another db, because SQLite doesn't have auto_increment, and I don't have easy access to anything else that does. I guess it could be a bug with db's that use sequences as well.. or maybe that's nothing to do with it).
Versions used:
- Test::MockObject - 1.01
- Class::DBI - 3.0.12
- mysql - 4.1.11